From fcbcbac8894e075de6d590c003bd01a1831ac2e5 Mon Sep 17 00:00:00 2001 From: Xianny <8582774+xianny@users.noreply.github.com> Date: Wed, 4 Dec 2019 13:08:08 -0800 Subject: [PATCH] Remove assetDataUtils everywhere (#2373) * remove assetDataUtils everywhere * export IAssetDataContract from @0x/contract-wrappers to allow @0x/instant to decode asset data synchronously * export generic function `decodeAssetDataOrThrow` and add ERC20Bridge support * export `hexUtils` from order-utils instead of contracts-test-utils --- .../asset-proxy/test/erc20bridge_proxy.ts | 13 +- contracts/asset-proxy/test/eth2dai_bridge.ts | 18 +- contracts/asset-proxy/test/kyber_bridge.ts | 10 +- contracts/asset-proxy/test/uniswap_bridge.ts | 16 +- contracts/coordinator/src/approval_factory.ts | 5 +- contracts/coordinator/src/hash_utils.ts | 7 +- contracts/coordinator/test/mixins.ts | 42 +- .../test/erc20-bridge-sampler.ts | 19 +- contracts/erc20/test/lib_erc20_token.ts | 21 +- .../exchange-forwarder/test/asset_test.ts | 10 +- .../exchange-libs/test/lib_fill_results.ts | 9 +- contracts/exchange-libs/test/lib_order.ts | 10 +- .../test/lib_zero_ex_transaction.ts | 17 +- contracts/exchange/test/internal.ts | 10 +- .../exchange/test/isolated_fill_order.ts | 6 +- .../test/lib_exchange_rich_error_decoder.ts | 32 +- contracts/exchange/test/reentrancy_tests.ts | 10 +- .../exchange/test/signature_validator.ts | 124 ++-- .../exchange/test/transactions_unit_tests.ts | 17 +- contracts/exchange/test/wrapper_unit_tests.ts | 17 +- contracts/extensions/CHANGELOG.json | 9 + contracts/extensions/package.json | 2 + contracts/extensions/test/dutch_auction.ts | 16 +- contracts/extensions/test/utils/index.ts | 21 + contracts/integrations/package.json | 2 +- .../test/coordinator/coordinator_test.ts | 16 +- .../test/exchange/transaction_test.ts | 6 +- .../test/forwarder/bridge_test.ts | 12 +- .../test/forwarder/forwarder_test_factory.ts | 16 +- .../framework/balances/local_balance_store.ts | 6 +- .../test/utils/zero_ex_governor_wrapper.ts | 6 +- contracts/multisig/test/zero_ex_governor.ts | 40 +- .../test/unit_tests/delegator_reward_test.ts | 63 +- .../staking/test/unit_tests/finalizer_test.ts | 17 +- .../test/unit_tests/lib_fixed_math_test.ts | 6 +- .../unit_tests/mixin_staking_pool_rewards.ts | 5 +- .../test/unit_tests/protocol_fees_test.ts | 5 +- .../test/unit_tests/stake_balances_test.ts | 19 +- .../staking/test/unit_tests/stake_test.ts | 8 +- .../test/unit_tests/staking_pool_test.ts | 11 +- contracts/test-utils/CHANGELOG.json | 11 +- contracts/test-utils/src/address_utils.ts | 5 +- contracts/test-utils/src/index.ts | 11 - contracts/test-utils/src/order_utils.ts | 5 +- contracts/utils/test/lib_eip712.ts | 6 +- contracts/utils/test/lib_rich_errors.ts | 6 +- packages/0x.js/src/index.ts | 7 +- .../test/order_prune_utils_test.ts | 13 +- packages/contract-artifacts/CHANGELOG.json | 9 + .../artifacts/IAssetData.json | 251 +++++++ packages/contract-wrappers/CHANGELOG.json | 9 + packages/contract-wrappers/package.json | 2 +- .../src/generated-wrappers/i_asset_data.ts | 643 ++++++++++++++++++ packages/contract-wrappers/src/index.ts | 1 + packages/instant/package.json | 2 +- packages/instant/src/index.umd.ts | 6 +- packages/instant/src/util/assert.ts | 5 +- .../instant/src/util/asset_data_encoder.ts | 19 + packages/order-utils/CHANGELOG.json | 13 + packages/order-utils/src/asset_data_utils.ts | 469 ------------- packages/order-utils/src/decode_asset_data.ts | 80 +++ packages/order-utils/src/index.ts | 5 +- .../order-utils/test/asset_data_utils_test.ts | 178 ----- packages/types/CHANGELOG.json | 9 + packages/types/src/index.ts | 14 +- packages/utils/CHANGELOG.json | 9 + .../utils}/src/hex_utils.ts | 53 +- packages/utils/src/index.ts | 1 + packages/utils/src/types.ts | 3 + yarn.lock | 83 +-- 70 files changed, 1498 insertions(+), 1129 deletions(-) create mode 100644 packages/contract-artifacts/artifacts/IAssetData.json create mode 100644 packages/contract-wrappers/src/generated-wrappers/i_asset_data.ts create mode 100644 packages/instant/src/util/asset_data_encoder.ts delete mode 100644 packages/order-utils/src/asset_data_utils.ts create mode 100644 packages/order-utils/src/decode_asset_data.ts delete mode 100644 packages/order-utils/test/asset_data_utils_test.ts rename {contracts/test-utils => packages/utils}/src/hex_utils.ts (56%) diff --git a/contracts/asset-proxy/test/erc20bridge_proxy.ts b/contracts/asset-proxy/test/erc20bridge_proxy.ts index 6e7388111a..b3a29c90ef 100644 --- a/contracts/asset-proxy/test/erc20bridge_proxy.ts +++ b/contracts/asset-proxy/test/erc20bridge_proxy.ts @@ -3,15 +3,12 @@ import { constants, expect, getRandomInteger, - hexLeftPad, - hexRightPad, - hexSlice, Numberish, randomAddress, } from '@0x/contracts-test-utils'; import { AuthorizableRevertErrors } from '@0x/contracts-utils'; import { AssetProxyId } from '@0x/types'; -import { AbiEncoder, BigNumber, StringRevertError } from '@0x/utils'; +import { AbiEncoder, BigNumber, hexUtils, StringRevertError } from '@0x/utils'; import { DecodedLogs } from 'ethereum-types'; import * as _ from 'lodash'; @@ -21,7 +18,7 @@ import { ERC20BridgeProxyContract, TestERC20BridgeContract } from './wrappers'; blockchainTests.resets('ERC20BridgeProxy unit tests', env => { const PROXY_ID = AssetProxyId.ERC20Bridge; - const BRIDGE_SUCCESS_RETURN_DATA = hexRightPad(PROXY_ID); + const BRIDGE_SUCCESS_RETURN_DATA = hexUtils.rightPad(PROXY_ID); let owner: string; let badCaller: string; let assetProxy: ERC20BridgeProxyContract; @@ -173,7 +170,7 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => { it('fails if asset data is truncated', async () => { const opts = createTransferFromOpts(); - const truncatedAssetData = hexSlice(encodeAssetData(opts.assetData), 0, -1); + const truncatedAssetData = hexUtils.slice(encodeAssetData(opts.assetData), 0, -1); const tx = assetProxy .transferFrom(truncatedAssetData, opts.from, opts.to, new BigNumber(opts.amount)) .awaitTransactionSuccessAsync(); @@ -197,7 +194,7 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => { const tx = transferFromAsync({ assetData: createAssetData({ bridgeData: createBridgeData({ - returnData: hexLeftPad('0x1'), + returnData: hexUtils.leftPad('0x1'), }), }), }); @@ -210,7 +207,7 @@ blockchainTests.resets('ERC20BridgeProxy unit tests', env => { const tx = transferFromAsync({ assetData: createAssetData({ bridgeData: createBridgeData({ - returnData: hexRightPad('0x1'), + returnData: hexUtils.rightPad('0x1'), }), }), }); diff --git a/contracts/asset-proxy/test/eth2dai_bridge.ts b/contracts/asset-proxy/test/eth2dai_bridge.ts index 445765e1cb..f102b146c6 100644 --- a/contracts/asset-proxy/test/eth2dai_bridge.ts +++ b/contracts/asset-proxy/test/eth2dai_bridge.ts @@ -4,13 +4,11 @@ import { expect, filterLogsToArguments, getRandomInteger, - hexLeftPad, - hexRandom, Numberish, randomAddress, } from '@0x/contracts-test-utils'; import { AssetProxyId } from '@0x/types'; -import { BigNumber, RawRevertError } from '@0x/utils'; +import { BigNumber, hexUtils, RawRevertError } from '@0x/utils'; import { DecodedLogs } from 'ethereum-types'; import * as _ from 'lodash'; @@ -39,7 +37,9 @@ blockchainTests.resets('Eth2DaiBridge unit tests', env => { describe('isValidSignature()', () => { it('returns success bytes', async () => { const LEGACY_WALLET_MAGIC_VALUE = '0xb0671381'; - const result = await testContract.isValidSignature(hexRandom(), hexRandom(_.random(0, 32))).callAsync(); + const result = await testContract + .isValidSignature(hexUtils.random(), hexUtils.random(_.random(0, 32))) + .callAsync(); expect(result).to.eq(LEGACY_WALLET_MAGIC_VALUE); }); }); @@ -71,7 +71,7 @@ blockchainTests.resets('Eth2DaiBridge unit tests', env => { fillAmount: getRandomInteger(1, 100e18), fromTokenBalance: getRandomInteger(1, 100e18), toTokentransferRevertReason: '', - toTokenTransferReturnData: hexLeftPad(1), + toTokenTransferReturnData: hexUtils.leftPad(1), ...opts, }; } @@ -111,7 +111,7 @@ blockchainTests.resets('Eth2DaiBridge unit tests', env => { _opts.toAddress, new BigNumber(_opts.amount), // ABI-encode the "from" token address as the bridge data. - hexLeftPad(_opts.fromTokenAddress as string), + hexUtils.leftPad(_opts.fromTokenAddress as string), ); const result = await bridgeTransferFromFn.callAsync(); const { logs } = await bridgeTransferFromFn.awaitTransactionSuccessAsync(); @@ -179,13 +179,13 @@ blockchainTests.resets('Eth2DaiBridge unit tests', env => { }); it('fails if `toTokenAddress.transfer()` returns false', async () => { - const opts = createWithdrawToOpts({ toTokenTransferReturnData: hexLeftPad(0) }); + const opts = createWithdrawToOpts({ toTokenTransferReturnData: hexUtils.leftPad(0) }); const tx = withdrawToAsync(opts); - return expect(tx).to.revertWith(new RawRevertError(hexLeftPad(0))); + return expect(tx).to.revertWith(new RawRevertError(hexUtils.leftPad(0))); }); it('succeeds if `toTokenAddress.transfer()` returns true', async () => { - await withdrawToAsync({ toTokenTransferReturnData: hexLeftPad(1) }); + await withdrawToAsync({ toTokenTransferReturnData: hexUtils.leftPad(1) }); }); }); }); diff --git a/contracts/asset-proxy/test/kyber_bridge.ts b/contracts/asset-proxy/test/kyber_bridge.ts index b61c154958..287ffb1efc 100644 --- a/contracts/asset-proxy/test/kyber_bridge.ts +++ b/contracts/asset-proxy/test/kyber_bridge.ts @@ -3,13 +3,11 @@ import { constants, expect, getRandomInteger, - hexLeftPad, - hexRandom, randomAddress, verifyEventsFromLogs, } from '@0x/contracts-test-utils'; import { AssetProxyId } from '@0x/types'; -import { BigNumber } from '@0x/utils'; +import { BigNumber, hexUtils } from '@0x/utils'; import { DecodedLogs } from 'ethereum-types'; import * as _ from 'lodash'; @@ -33,7 +31,9 @@ blockchainTests.resets('KyberBridge unit tests', env => { describe('isValidSignature()', () => { it('returns success bytes', async () => { const LEGACY_WALLET_MAGIC_VALUE = '0xb0671381'; - const result = await testContract.isValidSignature(hexRandom(), hexRandom(_.random(0, 32))).callAsync(); + const result = await testContract + .isValidSignature(hexUtils.random(), hexUtils.random(_.random(0, 32))) + .callAsync(); expect(result).to.eq(LEGACY_WALLET_MAGIC_VALUE); }); }); @@ -107,7 +107,7 @@ blockchainTests.resets('KyberBridge unit tests', env => { // Transfer amount. _opts.amount, // ABI-encode the input token address as the bridge data. - hexLeftPad(_opts.fromTokenAddress), + hexUtils.leftPad(_opts.fromTokenAddress), ); const result = await bridgeTransferFromFn.callAsync(); const { logs } = await bridgeTransferFromFn.awaitTransactionSuccessAsync(); diff --git a/contracts/asset-proxy/test/uniswap_bridge.ts b/contracts/asset-proxy/test/uniswap_bridge.ts index 4fad004808..36c096636d 100644 --- a/contracts/asset-proxy/test/uniswap_bridge.ts +++ b/contracts/asset-proxy/test/uniswap_bridge.ts @@ -5,13 +5,11 @@ import { filterLogs, filterLogsToArguments, getRandomInteger, - hexLeftPad, - hexRandom, Numberish, randomAddress, } from '@0x/contracts-test-utils'; import { AssetProxyId } from '@0x/types'; -import { BigNumber } from '@0x/utils'; +import { BigNumber, hexUtils } from '@0x/utils'; import { DecodedLogs } from 'ethereum-types'; import * as _ from 'lodash'; @@ -46,7 +44,9 @@ blockchainTests.resets('UniswapBridge unit tests', env => { describe('isValidSignature()', () => { it('returns success bytes', async () => { const LEGACY_WALLET_MAGIC_VALUE = '0xb0671381'; - const result = await testContract.isValidSignature(hexRandom(), hexRandom(_.random(0, 32))).callAsync(); + const result = await testContract + .isValidSignature(hexUtils.random(), hexUtils.random(_.random(0, 32))) + .callAsync(); expect(result).to.eq(LEGACY_WALLET_MAGIC_VALUE); }); }); @@ -126,7 +126,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => { // The amount to transfer to "to" new BigNumber(_opts.amount), // ABI-encoded "from" token address. - hexLeftPad(_opts.fromTokenAddress), + hexUtils.leftPad(_opts.fromTokenAddress), ); const result = await bridgeTransferFromFn.callAsync(); const receipt = await bridgeTransferFromFn.awaitTransactionSuccessAsync(); @@ -208,7 +208,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => { randomAddress(), randomAddress(), getRandomInteger(1, 1e18), - hexLeftPad(randomAddress()), + hexUtils.leftPad(randomAddress()), ) .awaitTransactionSuccessAsync(); return expect(tx).to.eventually.be.rejectedWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN'); @@ -282,7 +282,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => { randomAddress(), randomAddress(), getRandomInteger(1, 1e18), - hexLeftPad(wethTokenAddress), + hexUtils.leftPad(wethTokenAddress), ) .awaitTransactionSuccessAsync(); return expect(tx).to.eventually.be.rejectedWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN'); @@ -342,7 +342,7 @@ blockchainTests.resets('UniswapBridge unit tests', env => { randomAddress(), randomAddress(), getRandomInteger(1, 1e18), - hexLeftPad(randomAddress()), + hexUtils.leftPad(randomAddress()), ) .awaitTransactionSuccessAsync(); return expect(tx).to.eventually.be.rejectedWith('NO_UNISWAP_EXCHANGE_FOR_TOKEN'); diff --git a/contracts/coordinator/src/approval_factory.ts b/contracts/coordinator/src/approval_factory.ts index 701dc4a0a0..863b0b1b27 100644 --- a/contracts/coordinator/src/approval_factory.ts +++ b/contracts/coordinator/src/approval_factory.ts @@ -1,5 +1,6 @@ -import { hexConcat, signingUtils } from '@0x/contracts-test-utils'; +import { signingUtils } from '@0x/contracts-test-utils'; import { SignatureType, SignedZeroExTransaction } from '@0x/types'; +import { hexUtils } from '@0x/utils'; import { hashUtils } from './hash_utils'; import { SignedCoordinatorApproval } from './types'; @@ -27,7 +28,7 @@ export class ApprovalFactory { const signedApproval = { txOrigin, transaction, - signature: hexConcat(signatureBuff), + signature: hexUtils.concat(signatureBuff), }; return signedApproval; } diff --git a/contracts/coordinator/src/hash_utils.ts b/contracts/coordinator/src/hash_utils.ts index 5b6a10e7f3..6f83731b73 100644 --- a/contracts/coordinator/src/hash_utils.ts +++ b/contracts/coordinator/src/hash_utils.ts @@ -1,7 +1,6 @@ -import { hexConcat } from '@0x/contracts-test-utils'; import { eip712Utils } from '@0x/order-utils'; import { SignedZeroExTransaction } from '@0x/types'; -import { signTypedDataUtils } from '@0x/utils'; +import { hexUtils, signTypedDataUtils } from '@0x/utils'; export const hashUtils = { async getApprovalHashBufferAsync( @@ -22,7 +21,9 @@ export const hashUtils = { verifyingContract: string, txOrigin: string, ): Promise { - const hashHex = hexConcat(await hashUtils.getApprovalHashBufferAsync(transaction, verifyingContract, txOrigin)); + const hashHex = hexUtils.concat( + await hashUtils.getApprovalHashBufferAsync(transaction, verifyingContract, txOrigin), + ); return hashHex; }, }; diff --git a/contracts/coordinator/test/mixins.ts b/contracts/coordinator/test/mixins.ts index e5c2ee42a2..e143fa86e8 100644 --- a/contracts/coordinator/test/mixins.ts +++ b/contracts/coordinator/test/mixins.ts @@ -4,15 +4,13 @@ import { constants, ExchangeFunctionName, expect, - hexConcat, - hexSlice, randomAddress, TransactionFactory, transactionHashUtils, } from '@0x/contracts-test-utils'; import { LibBytesRevertErrors } from '@0x/contracts-utils'; import { SignatureType, SignedOrder } from '@0x/types'; -import { BigNumber, CoordinatorRevertErrors } from '@0x/utils'; +import { BigNumber, CoordinatorRevertErrors, hexUtils } from '@0x/utils'; import { ApprovalFactory } from '../src/approval_factory'; @@ -89,8 +87,8 @@ blockchainTests.resets('Mixins tests', env => { it('should revert with with the Illegal signature type', async () => { const data = constants.NULL_BYTES; const transaction = await transactionFactory.newSignedTransactionAsync({ data }); - transaction.signature = hexConcat( - hexSlice(transaction.signature, 0, transaction.signature.length - 1), + transaction.signature = hexUtils.concat( + hexUtils.slice(transaction.signature, 0, transaction.signature.length - 1), SignatureType.Illegal, ); const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); @@ -105,7 +103,7 @@ blockchainTests.resets('Mixins tests', env => { it('should revert with with the Invalid signature type', async () => { const data = constants.NULL_BYTES; const transaction = await transactionFactory.newSignedTransactionAsync({ data }); - transaction.signature = hexConcat(SignatureType.Invalid); + transaction.signature = hexUtils.concat(SignatureType.Invalid); const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); expect(mixins.getSignerAddress(transactionHash, transaction.signature).callAsync()).to.revertWith( new CoordinatorRevertErrors.SignatureError( @@ -118,8 +116,8 @@ blockchainTests.resets('Mixins tests', env => { it('should revert with with a signature type that equals `NSignatureTypes`', async () => { const data = constants.NULL_BYTES; const transaction = await transactionFactory.newSignedTransactionAsync({ data }); - transaction.signature = hexConcat( - hexSlice(transaction.signature, 0, transaction.signature.length - 1), + transaction.signature = hexUtils.concat( + hexUtils.slice(transaction.signature, 0, transaction.signature.length - 1), SignatureType.NSignatureTypes, ); const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); @@ -134,8 +132,8 @@ blockchainTests.resets('Mixins tests', env => { it("should revert with with a signature type that isn't supported", async () => { const data = constants.NULL_BYTES; const transaction = await transactionFactory.newSignedTransactionAsync({ data }); - transaction.signature = hexConcat( - hexSlice(transaction.signature, 0, transaction.signature.length - 1), + transaction.signature = hexUtils.concat( + hexUtils.slice(transaction.signature, 0, transaction.signature.length - 1), SignatureType.Wallet, ); const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); @@ -296,10 +294,10 @@ blockchainTests.resets('Mixins tests', env => { const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress); - const signature = hexConcat( - hexSlice(approval.signature, 0, 2), + const signature = hexUtils.concat( + hexUtils.slice(approval.signature, 0, 2), '0xFFFFFFFF', - hexSlice(approval.signature, 6), + hexUtils.slice(approval.signature, 6), ); const tx = mixins .assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [ @@ -432,10 +430,10 @@ blockchainTests.resets('Mixins tests', env => { const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const approval = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress); - const signature = hexConcat( - hexSlice(approval.signature, 0, 2), + const signature = hexUtils.concat( + hexUtils.slice(approval.signature, 0, 2), '0xFFFFFFFF', - hexSlice(approval.signature, 6), + hexUtils.slice(approval.signature, 6), ); const tx = mixins .assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [ @@ -454,10 +452,10 @@ blockchainTests.resets('Mixins tests', env => { const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const approval1 = await approvalFactory1.newSignedApprovalAsync(transaction, transactionSignerAddress); const approval2 = await approvalFactory2.newSignedApprovalAsync(transaction, transactionSignerAddress); - const approvalSignature2 = hexConcat( - hexSlice(approval2.signature, 0, 2), + const approvalSignature2 = hexUtils.concat( + hexUtils.slice(approval2.signature, 0, 2), '0xFFFFFFFF', - hexSlice(approval2.signature, 6), + hexUtils.slice(approval2.signature, 6), ); const tx = mixins .assertValidCoordinatorApprovals(transaction, transactionSignerAddress, transaction.signature, [ @@ -476,10 +474,10 @@ blockchainTests.resets('Mixins tests', env => { const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); const transaction = await transactionFactory.newSignedTransactionAsync({ data }); const approval2 = await approvalFactory2.newSignedApprovalAsync(transaction, transactionSignerAddress); - const approvalSignature2 = hexConcat( - hexSlice(approval2.signature, 0, 2), + const approvalSignature2 = hexUtils.concat( + hexUtils.slice(approval2.signature, 0, 2), '0xFFFFFFFF', - hexSlice(approval2.signature, 6), + hexUtils.slice(approval2.signature, 6), ); const tx = mixins .assertValidCoordinatorApprovals(transaction, approvalSignerAddress1, transaction.signature, [ diff --git a/contracts/erc20-bridge-sampler/test/erc20-bridge-sampler.ts b/contracts/erc20-bridge-sampler/test/erc20-bridge-sampler.ts index d008c938b0..f8bf44132f 100644 --- a/contracts/erc20-bridge-sampler/test/erc20-bridge-sampler.ts +++ b/contracts/erc20-bridge-sampler/test/erc20-bridge-sampler.ts @@ -4,15 +4,10 @@ import { expect, getRandomInteger, getRandomPortion, - hexConcat, - hexHash, - hexLeftPad, - hexRandom, randomAddress, - toHex, } from '@0x/contracts-test-utils'; import { Order, OrderInfo } from '@0x/types'; -import { BigNumber } from '@0x/utils'; +import { BigNumber, hexUtils } from '@0x/utils'; import * as _ from 'lodash'; import { artifacts } from './artifacts'; @@ -31,8 +26,8 @@ blockchainTests('erc20-bridge-sampler', env => { const ETH2DAI_SALT = '0xb713b61bb9bb2958a0f5d1534b21e94fc68c4c0c034b0902ed844f2f6cd1b4f7'; const UNISWAP_BASE_SALT = '0x1d6a6a0506b0b4a554b907a4c29d9f4674e461989d9c1921feb17b26716385ab'; const ERC20_PROXY_ID = '0xf47261b0'; - const INVALID_ASSET_PROXY_ASSET_DATA = hexConcat('0xf47261b1', hexLeftPad(randomAddress())); - const INVALID_ASSET_DATA = hexRandom(37); + const INVALID_ASSET_PROXY_ASSET_DATA = hexUtils.concat('0xf47261b1', hexUtils.leftPad(randomAddress())); + const INVALID_ASSET_DATA = hexUtils.random(37); const SELL_SOURCES = ['Eth2Dai', 'Kyber', 'Uniswap']; const BUY_SOURCES = ['Eth2Dai', 'Uniswap']; const EMPTY_ORDERS_ERROR = 'EMPTY_ORDERS'; @@ -60,7 +55,7 @@ blockchainTests('erc20-bridge-sampler', env => { }); function getPackedHash(...args: string[]): string { - return hexHash(hexConcat(...args.map(a => toHex(a)))); + return hexUtils.hash(hexUtils.concat(...args.map(a => hexUtils.toHex(a)))); } function getUniswapExchangeSalt(tokenAddress: string): string { @@ -198,7 +193,7 @@ blockchainTests('erc20-bridge-sampler', env => { } function getDeterministicOrderInfo(order: Order): OrderInfo { - const hash = getPackedHash(hexLeftPad(order.salt, 32)); + const hash = getPackedHash(hexUtils.leftPad(order.salt, 32)); return { orderHash: hash, orderStatus: new BigNumber(hash).mod(255).toNumber(), @@ -207,7 +202,7 @@ blockchainTests('erc20-bridge-sampler', env => { } function getERC20AssetData(tokenAddress: string): string { - return hexConcat(ERC20_PROXY_ID, hexLeftPad(tokenAddress)); + return hexUtils.concat(ERC20_PROXY_ID, hexUtils.leftPad(tokenAddress)); } function getSampleAmounts(tokenAddress: string, count?: number): BigNumber[] { @@ -234,7 +229,7 @@ blockchainTests('erc20-bridge-sampler', env => { takerAssetData: getERC20AssetData(takerToken), makerFeeAssetData: getERC20AssetData(randomAddress()), takerFeeAssetData: getERC20AssetData(randomAddress()), - salt: new BigNumber(hexRandom()), + salt: new BigNumber(hexUtils.random()), expirationTimeSeconds: getRandomInteger(0, 2 ** 32), }; } diff --git a/contracts/erc20/test/lib_erc20_token.ts b/contracts/erc20/test/lib_erc20_token.ts index 78b842a0bb..1f3eee4453 100644 --- a/contracts/erc20/test/lib_erc20_token.ts +++ b/contracts/erc20/test/lib_erc20_token.ts @@ -3,11 +3,10 @@ import { constants, expect, getRandomInteger, - hexLeftPad, randomAddress, verifyEventsFromLogs, } from '@0x/contracts-test-utils'; -import { RawRevertError, StringRevertError } from '@0x/utils'; +import { hexUtils, RawRevertError, StringRevertError } from '@0x/utils'; import { TestLibERC20TokenContract, TestLibERC20TokenTargetEvents } from './wrappers'; @@ -17,11 +16,11 @@ blockchainTests('LibERC20Token', env => { let testContract: TestLibERC20TokenContract; const REVERT_STRING = 'WHOOPSIE'; const ENCODED_REVERT = new StringRevertError(REVERT_STRING).encode(); - const ENCODED_TRUE = hexLeftPad(1); - const ENCODED_FALSE = hexLeftPad(0); - const ENCODED_TWO = hexLeftPad(2); - const ENCODED_SHORT_TRUE = hexLeftPad(2, 31); - const ENCODED_LONG_TRUE = hexLeftPad(2, 33); + const ENCODED_TRUE = hexUtils.leftPad(1); + const ENCODED_FALSE = hexUtils.leftPad(0); + const ENCODED_TWO = hexUtils.leftPad(2); + const ENCODED_SHORT_TRUE = hexUtils.leftPad(2, 31); + const ENCODED_LONG_TRUE = hexUtils.leftPad(2, 33); before(async () => { testContract = await TestLibERC20TokenContract.deployFrom0xArtifactAsync( @@ -301,14 +300,14 @@ blockchainTests('LibERC20Token', env => { describe('decimals()', () => { const DEFAULT_DECIMALS = 18; - const ENCODED_ZERO = hexLeftPad(0); - const ENCODED_SHORT_ZERO = hexLeftPad(0, 31); - const ENCODED_LONG_ZERO = hexLeftPad(0, 33); + const ENCODED_ZERO = hexUtils.leftPad(0); + const ENCODED_SHORT_ZERO = hexUtils.leftPad(0, 31); + const ENCODED_LONG_ZERO = hexUtils.leftPad(0, 33); const randomDecimals = () => Math.floor(Math.random() * 256) + 1; it('returns the number of decimals defined by the token', async () => { const decimals = randomDecimals(); - const encodedDecimals = hexLeftPad(decimals); + const encodedDecimals = hexUtils.leftPad(decimals); const result = await testContract.testDecimals(false, ENCODED_REVERT, encodedDecimals).callAsync(); return expect(result).to.bignumber.eq(decimals); }); diff --git a/contracts/exchange-forwarder/test/asset_test.ts b/contracts/exchange-forwarder/test/asset_test.ts index fab1391d59..5da23afbd4 100644 --- a/contracts/exchange-forwarder/test/asset_test.ts +++ b/contracts/exchange-forwarder/test/asset_test.ts @@ -16,12 +16,10 @@ import { constants, expect, getRandomInteger, - hexRandom, - hexSlice, randomAddress, verifyEventsFromLogs, } from '@0x/contracts-test-utils'; -import { BigNumber, ExchangeForwarderRevertErrors } from '@0x/utils'; +import { BigNumber, ExchangeForwarderRevertErrors, hexUtils } from '@0x/utils'; import { artifacts } from './artifacts'; import { TestForwarderContract } from './wrappers'; @@ -76,7 +74,7 @@ blockchainTests('Supported asset type unit tests', env => { erc721AssetData = assetDataEncoder.ERC721Token(erc721Token.address, nftId).getABIEncodedTransactionData(); bridgeAddress = randomAddress(); - bridgeData = hexRandom(); + bridgeData = hexUtils.random(); erc20BridgeAssetData = assetDataEncoder .ERC20Bridge(erc20Token.address, bridgeAddress, bridgeData) .getABIEncodedTransactionData(); @@ -171,12 +169,12 @@ blockchainTests('Supported asset type unit tests', env => { ); }); it('reverts if assetData is unsupported', async () => { - const randomBytes = hexRandom(); + const randomBytes = hexUtils.random(); const tx = forwarder .transferAssetToSender(randomBytes, TRANSFER_AMOUNT) .awaitTransactionSuccessAsync({ from: receiver }); const expectedError = new ExchangeForwarderRevertErrors.UnsupportedAssetProxyError( - hexSlice(randomBytes, 0, 4), + hexUtils.slice(randomBytes, 0, 4), ); return expect(tx).to.revertWith(expectedError); }); diff --git a/contracts/exchange-libs/test/lib_fill_results.ts b/contracts/exchange-libs/test/lib_fill_results.ts index 2d8d54ea41..a47240e8f3 100644 --- a/contracts/exchange-libs/test/lib_fill_results.ts +++ b/contracts/exchange-libs/test/lib_fill_results.ts @@ -3,13 +3,12 @@ import { constants, describe, expect, - hexRandom, testCombinatoriallyWithReferenceFunc, uint256Values, } from '@0x/contracts-test-utils'; import { SafeMathRevertErrors } from '@0x/contracts-utils'; import { FillResults, MatchedFillResults, Order } from '@0x/types'; -import { BigNumber, LibMathRevertErrors } from '@0x/utils'; +import { BigNumber, hexUtils, LibMathRevertErrors } from '@0x/utils'; import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; @@ -46,9 +45,9 @@ blockchainTests('LibFillResults', env => { exchangeAddress: constants.NULL_ADDRESS, }; - const randomAddress = () => hexRandom(constants.ADDRESS_LENGTH); - const randomAssetData = () => hexRandom(36); - const randomUint256 = () => new BigNumber(hexRandom(constants.WORD_LENGTH)); + const randomAddress = () => hexUtils.random(constants.ADDRESS_LENGTH); + const randomAssetData = () => hexUtils.random(36); + const randomUint256 = () => new BigNumber(hexUtils.random(constants.WORD_LENGTH)); let libsContract: TestLibFillResultsContract; let makerAddressLeft: string; diff --git a/contracts/exchange-libs/test/lib_order.ts b/contracts/exchange-libs/test/lib_order.ts index 730e2db1fa..7b8a9ea340 100644 --- a/contracts/exchange-libs/test/lib_order.ts +++ b/contracts/exchange-libs/test/lib_order.ts @@ -1,7 +1,7 @@ -import { blockchainTests, constants, describe, expect, hexRandom, orderHashUtils } from '@0x/contracts-test-utils'; +import { blockchainTests, constants, describe, expect, orderHashUtils } from '@0x/contracts-test-utils'; import { eip712Utils } from '@0x/order-utils'; import { Order } from '@0x/types'; -import { BigNumber, signTypedDataUtils } from '@0x/utils'; +import { BigNumber, hexUtils, signTypedDataUtils } from '@0x/utils'; import * as ethUtil from 'ethereumjs-util'; import * as _ from 'lodash'; @@ -12,10 +12,10 @@ import { artifacts } from './artifacts'; blockchainTests('LibOrder', env => { let libOrderContract: TestLibOrderContract; - const randomAddress = () => hexRandom(constants.ADDRESS_LENGTH); - const randomHash = () => hexRandom(constants.WORD_LENGTH); + const randomAddress = () => hexUtils.random(constants.ADDRESS_LENGTH); + const randomHash = () => hexUtils.random(constants.WORD_LENGTH); const randomUint256 = () => new BigNumber(randomHash()); - const randomAssetData = () => hexRandom(36); + const randomAssetData = () => hexUtils.random(36); const EMPTY_ORDER: Order = { exchangeAddress: constants.NULL_ADDRESS, diff --git a/contracts/exchange-libs/test/lib_zero_ex_transaction.ts b/contracts/exchange-libs/test/lib_zero_ex_transaction.ts index 8462c406cb..c13e94dcef 100644 --- a/contracts/exchange-libs/test/lib_zero_ex_transaction.ts +++ b/contracts/exchange-libs/test/lib_zero_ex_transaction.ts @@ -1,14 +1,7 @@ -import { - blockchainTests, - constants, - describe, - expect, - hexRandom, - transactionHashUtils, -} from '@0x/contracts-test-utils'; +import { blockchainTests, constants, describe, expect, transactionHashUtils } from '@0x/contracts-test-utils'; import { eip712Utils } from '@0x/order-utils'; import { ZeroExTransaction } from '@0x/types'; -import { BigNumber, signTypedDataUtils } from '@0x/utils'; +import { BigNumber, hexUtils, signTypedDataUtils } from '@0x/utils'; import * as ethUtil from 'ethereumjs-util'; import * as _ from 'lodash'; @@ -19,10 +12,10 @@ import { artifacts } from './artifacts'; blockchainTests('LibZeroExTransaction', env => { let libZeroExTransactionContract: TestLibZeroExTransactionContract; - const randomAddress = () => hexRandom(constants.ADDRESS_LENGTH); - const randomHash = () => hexRandom(constants.WORD_LENGTH); + const randomAddress = () => hexUtils.random(constants.ADDRESS_LENGTH); + const randomHash = () => hexUtils.random(constants.WORD_LENGTH); const randomUint256 = () => new BigNumber(randomHash()); - const randomAssetData = () => hexRandom(36); + const randomAssetData = () => hexUtils.random(36); const EMPTY_TRANSACTION: ZeroExTransaction = { salt: constants.ZERO_AMOUNT, diff --git a/contracts/exchange/test/internal.ts b/contracts/exchange/test/internal.ts index eb8a2425ff..98fca2e9fd 100644 --- a/contracts/exchange/test/internal.ts +++ b/contracts/exchange/test/internal.ts @@ -1,8 +1,8 @@ import { ReferenceFunctions as LibReferenceFunctions } from '@0x/contracts-exchange-libs'; -import { blockchainTests, constants, expect, hexRandom, orderHashUtils } from '@0x/contracts-test-utils'; +import { blockchainTests, constants, expect, orderHashUtils } from '@0x/contracts-test-utils'; import { SafeMathRevertErrors } from '@0x/contracts-utils'; import { Order } from '@0x/types'; -import { BigNumber, ExchangeRevertErrors } from '@0x/utils'; +import { BigNumber, ExchangeRevertErrors, hexUtils } from '@0x/utils'; import { Web3Wrapper } from '@0x/web3-wrapper'; import { LogWithDecodedArgs } from 'ethereum-types'; import * as _ from 'lodash'; @@ -16,9 +16,9 @@ import { blockchainTests('Exchange core internal functions', env => { const CHAIN_ID = 1337; const ONE_ETHER = constants.ONE_ETHER; - const randomAddress = () => hexRandom(constants.ADDRESS_LENGTH); - const randomHash = () => hexRandom(constants.WORD_LENGTH); - const randomAssetData = () => hexRandom(36); + const randomAddress = () => hexUtils.random(constants.ADDRESS_LENGTH); + const randomHash = () => hexUtils.random(constants.WORD_LENGTH); + const randomAssetData = () => hexUtils.random(36); let testExchange: TestExchangeInternalsContract; let senderAddress: string; const DEFAULT_PROTOCOL_MULTIPLIER = new BigNumber(150000); diff --git a/contracts/exchange/test/isolated_fill_order.ts b/contracts/exchange/test/isolated_fill_order.ts index 7f552f0818..7a6f736d17 100644 --- a/contracts/exchange/test/isolated_fill_order.ts +++ b/contracts/exchange/test/isolated_fill_order.ts @@ -1,8 +1,8 @@ import { LibMathRevertErrors, ReferenceFunctions as LibReferenceFunctions } from '@0x/contracts-exchange-libs'; -import { blockchainTests, constants, expect, hexRandom } from '@0x/contracts-test-utils'; +import { blockchainTests, constants, expect } from '@0x/contracts-test-utils'; import { SafeMathRevertErrors } from '@0x/contracts-utils'; import { FillResults, OrderInfo, OrderStatus, SignatureType } from '@0x/types'; -import { BigNumber, ExchangeRevertErrors } from '@0x/utils'; +import { BigNumber, ExchangeRevertErrors, hexUtils } from '@0x/utils'; import * as _ from 'lodash'; import { @@ -16,7 +16,7 @@ import { } from './utils/isolated_exchange_wrapper'; blockchainTests('Isolated fillOrder() tests', env => { - const randomAddress = () => hexRandom(constants.ADDRESS_LENGTH); + const randomAddress = () => hexUtils.random(constants.ADDRESS_LENGTH); const getCurrentTime = () => Math.floor(_.now() / 1000); const { ZERO_AMOUNT, ONE_ETHER, MAX_UINT256_ROOT } = constants; const ONE_DAY = 60 * 60 * 24; diff --git a/contracts/exchange/test/lib_exchange_rich_error_decoder.ts b/contracts/exchange/test/lib_exchange_rich_error_decoder.ts index 9136f13dfd..51eda2344b 100644 --- a/contracts/exchange/test/lib_exchange_rich_error_decoder.ts +++ b/contracts/exchange/test/lib_exchange_rich_error_decoder.ts @@ -1,14 +1,6 @@ -import { - blockchainTests, - constants, - expect, - hexRandom, - OrderStatus, - orderUtils, - randomAddress, -} from '@0x/contracts-test-utils'; +import { blockchainTests, constants, expect, OrderStatus, orderUtils, randomAddress } from '@0x/contracts-test-utils'; import { generatePseudoRandomSalt } from '@0x/order-utils'; -import { BigNumber, ExchangeRevertErrors, RevertError } from '@0x/utils'; +import { BigNumber, ExchangeRevertErrors, hexUtils, RevertError } from '@0x/utils'; import * as _ from 'lodash'; import { artifacts } from './artifacts'; @@ -63,9 +55,9 @@ blockchainTests.resets('LibExchangeRichErrorDecoder', ({ provider, txDefaults }) const orderHash = orderUtils.generatePseudoRandomOrderHash(); const signer = randomAddress(); const validator = randomAddress(); - const data = hexRandom(ERROR_DATA_LENGTH); - const signature = hexRandom(SIGNATURE_LENGTH); - const errorData = hexRandom(ERROR_DATA_LENGTH); + const data = hexUtils.random(ERROR_DATA_LENGTH); + const signature = hexUtils.random(SIGNATURE_LENGTH); + const errorData = hexUtils.random(ERROR_DATA_LENGTH); createDecodeTest(ExchangeRevertErrors.SignatureError, [errorCode, orderHash, signer, signature]); createDecodeTest(ExchangeRevertErrors.SignatureValidatorNotApprovedError, [signer, validator]); createDecodeTest(ExchangeRevertErrors.EIP1271SignatureError, [validator, data, signature, errorData]); @@ -114,7 +106,7 @@ blockchainTests.resets('LibExchangeRichErrorDecoder', ({ provider, txDefaults }) (() => { const assetProxyAddress = randomAddress(); createDecodeTest(ExchangeRevertErrors.AssetProxyExistsError, [ - hexRandom(ASSET_PROXY_ID_LENGTH), + hexUtils.random(ASSET_PROXY_ID_LENGTH), assetProxyAddress, ]); })(); @@ -122,14 +114,14 @@ blockchainTests.resets('LibExchangeRichErrorDecoder', ({ provider, txDefaults }) (() => { const errorCode = ExchangeRevertErrors.AssetProxyDispatchErrorCode.UnknownAssetProxy; const orderHash = orderUtils.generatePseudoRandomOrderHash(); - const assetData = hexRandom(ASSET_DATA_LENGTH); + const assetData = hexUtils.random(ASSET_DATA_LENGTH); createDecodeTest(ExchangeRevertErrors.AssetProxyDispatchError, [errorCode, orderHash, assetData]); })(); (() => { const orderHash = orderUtils.generatePseudoRandomOrderHash(); - const assetData = hexRandom(ASSET_DATA_LENGTH); - const errorData = hexRandom(ERROR_DATA_LENGTH); + const assetData = hexUtils.random(ASSET_DATA_LENGTH); + const errorData = hexUtils.random(ERROR_DATA_LENGTH); createDecodeTest(ExchangeRevertErrors.AssetProxyTransferError, [orderHash, assetData, errorData]); })(); @@ -147,14 +139,14 @@ blockchainTests.resets('LibExchangeRichErrorDecoder', ({ provider, txDefaults }) (() => { const transactionHash = orderUtils.generatePseudoRandomOrderHash(); - const errorData = hexRandom(ERROR_DATA_LENGTH); + const errorData = hexUtils.random(ERROR_DATA_LENGTH); createDecodeTest(ExchangeRevertErrors.TransactionExecutionError, [transactionHash, errorData]); })(); (() => { const errorCode = ExchangeRevertErrors.IncompleteFillErrorCode.IncompleteMarketSellOrders; - const expectedAmount = new BigNumber(hexRandom(WORD_LENGTH)); - const actualAmount = new BigNumber(hexRandom(WORD_LENGTH)); + const expectedAmount = new BigNumber(hexUtils.random(WORD_LENGTH)); + const actualAmount = new BigNumber(hexUtils.random(WORD_LENGTH)); createDecodeTest(ExchangeRevertErrors.IncompleteFillError, [errorCode, expectedAmount, actualAmount]); })(); }); diff --git a/contracts/exchange/test/reentrancy_tests.ts b/contracts/exchange/test/reentrancy_tests.ts index a57e712aeb..0a4f3ede55 100644 --- a/contracts/exchange/test/reentrancy_tests.ts +++ b/contracts/exchange/test/reentrancy_tests.ts @@ -1,5 +1,5 @@ -import { blockchainTests, constants, describe, expect, hexRandom } from '@0x/contracts-test-utils'; -import { BigNumber } from '@0x/utils'; +import { blockchainTests, constants, describe, expect } from '@0x/contracts-test-utils'; +import { BigNumber, hexUtils } from '@0x/utils'; import { DataItem, MethodAbi, TupleDataItem } from 'ethereum-types'; import * as _ from 'lodash'; @@ -47,11 +47,11 @@ blockchainTests.resets('Reentrancy Tests', env => { } // Handle bytes. if (item.type === 'bytes') { - return hexRandom(36); + return hexUtils.random(36); } // Handle addresses. if (item.type === 'address') { - return hexRandom(constants.ADDRESS_LENGTH); + return hexUtils.random(constants.ADDRESS_LENGTH); } // Handle bools. if (item.type === 'bool') { @@ -84,7 +84,7 @@ blockchainTests.resets('Reentrancy Tests', env => { m = /^bytes(\d+)$/.exec(item.type); if (m) { const size = parseInt(m[1], 10) || 32; - return hexRandom(size); + return hexUtils.random(size); } throw new Error(`Unhandled input type: ${item.type}`); } diff --git a/contracts/exchange/test/signature_validator.ts b/contracts/exchange/test/signature_validator.ts index fea72881a5..0600980176 100644 --- a/contracts/exchange/test/signature_validator.ts +++ b/contracts/exchange/test/signature_validator.ts @@ -5,8 +5,6 @@ import { blockchainTests, constants, expect, - hexConcat, - hexRandom, LogDecoder, OrderFactory, orderHashUtils, @@ -16,7 +14,7 @@ import { transactionHashUtils, } from '@0x/contracts-test-utils'; import { SignatureType, SignedOrder, SignedZeroExTransaction } from '@0x/types'; -import { BigNumber, ExchangeRevertErrors, StringRevertError } from '@0x/utils'; +import { BigNumber, ExchangeRevertErrors, hexUtils, StringRevertError } from '@0x/utils'; import { LogWithDecodedArgs } from 'ethereum-types'; import ethUtil = require('ethereumjs-util'); @@ -89,11 +87,11 @@ blockchainTests.resets('MixinSignatureValidator', env => { }); const SIGNATURE_LENGTH = 65; - const generateRandomSignature = (): string => hexRandom(SIGNATURE_LENGTH); + const generateRandomSignature = (): string => hexUtils.random(SIGNATURE_LENGTH); const hashBytes = (bytesHex: string): string => ethUtil.bufferToHex(ethUtil.sha3(ethUtil.toBuffer(bytesHex))); const signDataHex = (dataHex: string, privateKey: Buffer): string => { const ecSignature = ethUtil.ecsign(ethUtil.toBuffer(dataHex), privateKey); - return hexConcat(ecSignature.v, ecSignature.r, ecSignature.s); + return hexUtils.concat(ecSignature.v, ecSignature.r, ecSignature.s); }; type ValidateHashSignatureAsync = ( @@ -123,7 +121,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { it('should revert when signature type is unsupported', async () => { const hashHex = getCurrentHashHex(); - const signatureHex = hexConcat(SignatureType.NSignatureTypes); + const signatureHex = hexUtils.concat(SignatureType.NSignatureTypes); const expectedError = new ExchangeRevertErrors.SignatureError( ExchangeRevertErrors.SignatureErrorCode.Unsupported, hashHex, @@ -136,7 +134,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { it('should revert when SignatureType=Illegal', async () => { const hashHex = getCurrentHashHex(); - const signatureHex = hexConcat(SignatureType.Illegal); + const signatureHex = hexUtils.concat(SignatureType.Illegal); const expectedError = new ExchangeRevertErrors.SignatureError( ExchangeRevertErrors.SignatureErrorCode.Illegal, hashHex, @@ -149,14 +147,14 @@ blockchainTests.resets('MixinSignatureValidator', env => { it('should return false when SignatureType=Invalid and signature has a length of zero', async () => { const hashHex = getCurrentHashHex(); - const signatureHex = hexConcat(SignatureType.Invalid); + const signatureHex = hexUtils.concat(SignatureType.Invalid); const isValidSignature = await validateAsync(hashHex, signerAddress, signatureHex); expect(isValidSignature).to.be.false(); }); it('should revert when SignatureType=Invalid and signature length is non-zero', async () => { const hashHex = getCurrentHashHex(); - const signatureHex = hexConcat('0xdeadbeef', SignatureType.Invalid); + const signatureHex = hexUtils.concat('0xdeadbeef', SignatureType.Invalid); const expectedError = new ExchangeRevertErrors.SignatureError( ExchangeRevertErrors.SignatureErrorCode.InvalidLength, hashHex, @@ -169,14 +167,14 @@ blockchainTests.resets('MixinSignatureValidator', env => { it('should return true when SignatureType=EIP712 and signature is valid', async () => { const hashHex = getCurrentHashHex(); - const signatureHex = hexConcat(signDataHex(hashHex, signerPrivateKey), SignatureType.EIP712); + const signatureHex = hexUtils.concat(signDataHex(hashHex, signerPrivateKey), SignatureType.EIP712); const isValidSignature = await validateAsync(hashHex, signerAddress, signatureHex); expect(isValidSignature).to.be.true(); }); it('should return false when SignatureType=EIP712 and signature is invalid', async () => { const hashHex = getCurrentHashHex(); - const signatureHex = hexConcat(generateRandomSignature(), SignatureType.EIP712); + const signatureHex = hexUtils.concat(generateRandomSignature(), SignatureType.EIP712); const isValidSignature = await validateAsync(hashHex, signerAddress, signatureHex); expect(isValidSignature).to.be.false(); }); @@ -187,7 +185,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { const orderHashWithEthSignPrefixHex = ethUtil.bufferToHex( ethUtil.hashPersonalMessage(ethUtil.toBuffer(hashHex)), ); - const signatureHex = hexConcat( + const signatureHex = hexUtils.concat( signDataHex(orderHashWithEthSignPrefixHex, signerPrivateKey), SignatureType.EthSign, ); @@ -198,7 +196,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { it('should return false when SignatureType=EthSign and signature is invalid', async () => { const hashHex = getCurrentHashHex(); // Create EthSign signature - const signatureHex = hexConcat(generateRandomSignature(), SignatureType.EthSign); + const signatureHex = hexUtils.concat(generateRandomSignature(), SignatureType.EthSign); const isValidSignature = await validateAsync(hashHex, signerAddress, signatureHex); expect(isValidSignature).to.be.false(); }); @@ -208,7 +206,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { // Doesn't have to contain a real signature since our wallet contract // just does a hash comparison. const signatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(signatureDataHex, SignatureType.Wallet); + const signatureHex = hexUtils.concat(signatureDataHex, SignatureType.Wallet); const isValidSignature = await validateAsync( hashHex, validatorWallet.address, @@ -225,7 +223,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { // just does a hash comparison. const signatureDataHex = generateRandomSignature(); const notSignatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(notSignatureDataHex, SignatureType.Wallet); + const signatureHex = hexUtils.concat(notSignatureDataHex, SignatureType.Wallet); // Validate signature const isValidSignature = await validateAsync( hashHex, @@ -241,7 +239,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { const hashHex = getCurrentHashHex(validatorWallet.address); // Doesn't have to contain a real signature since our wallet contract // just does a hash comparison. - const signatureHex = hexConcat(generateRandomSignature(), SignatureType.Wallet); + const signatureHex = hexUtils.concat(generateRandomSignature(), SignatureType.Wallet); const expectedError = new ExchangeRevertErrors.SignatureWalletError( hashHex, validatorWallet.address, @@ -254,7 +252,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { it('should revert when signer is an EOA and SignatureType=Wallet', async () => { const hashHex = getCurrentHashHex(); - const signatureHex = hexConcat(SignatureType.Wallet); + const signatureHex = hexUtils.concat(SignatureType.Wallet); const expectedError = new ExchangeRevertErrors.SignatureWalletError( hashHex, signerAddress, @@ -267,7 +265,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { it('should return false when validator returns `true` and SignatureType=Wallet', async () => { const hashHex = getCurrentHashHex(); - const signatureHex = hexConcat(SignatureType.Wallet); + const signatureHex = hexUtils.concat(SignatureType.Wallet); const isValidSignature = await validateAsync( hashHex, validatorWallet.address, @@ -279,7 +277,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { it('should revert when validator returns nothing and SignatureType=Wallet', async () => { const hashHex = getCurrentHashHex(validatorWallet.address); - const signatureHex = hexConcat(SignatureType.Wallet); + const signatureHex = hexUtils.concat(SignatureType.Wallet); const expectedError = new ExchangeRevertErrors.SignatureWalletError( hashHex, validatorWallet.address, @@ -299,7 +297,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { const hashHex = getCurrentHashHex(validatorWallet.address); // Doesn't have to contain a real signature since our wallet contract // just does a hash comparison. - const signatureHex = hexConcat(generateRandomSignature(), SignatureType.Wallet); + const signatureHex = hexUtils.concat(generateRandomSignature(), SignatureType.Wallet); const expectedError = new ExchangeRevertErrors.SignatureWalletError( hashHex, validatorWallet.address, @@ -315,14 +313,14 @@ blockchainTests.resets('MixinSignatureValidator', env => { // Presign the hash await exchange.preSign(hashHex).awaitTransactionSuccessAsync({ from: signerAddress }); // Validate presigned signature - const signatureHex = hexConcat(SignatureType.PreSigned); + const signatureHex = hexUtils.concat(SignatureType.PreSigned); const isValidSignature = await validateAsync(hashHex, signerAddress, signatureHex); expect(isValidSignature).to.be.true(); }); it('should return false when SignatureType=Presigned and signer has not presigned hash', async () => { const hashHex = getCurrentHashHex(); - const signatureHex = hexConcat(SignatureType.PreSigned); + const signatureHex = hexUtils.concat(SignatureType.PreSigned); const isValidSignature = await validateAsync(hashHex, signerAddress, signatureHex); expect(isValidSignature).to.be.false(); }); @@ -355,7 +353,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { }; it('should revert when signerAddress == 0', async () => { - const signatureHex = hexConcat(SignatureType.EIP712); + const signatureHex = hexUtils.concat(SignatureType.EIP712); const expectedError = new ExchangeRevertErrors.SignatureError( ExchangeRevertErrors.SignatureErrorCode.InvalidSigner, hashHex, @@ -367,7 +365,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { }); it('should revert when SignatureType=Validator', async () => { - const signatureHex = hexConcat(SignatureType.Validator); + const signatureHex = hexUtils.concat(SignatureType.Validator); const expectedError = new ExchangeRevertErrors.SignatureError( ExchangeRevertErrors.SignatureErrorCode.InappropriateSignatureType, hashHex, @@ -379,7 +377,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { }); it('should revert when SignatureType=EIP1271Wallet', async () => { - const signatureHex = hexConcat(SignatureType.EIP1271Wallet); + const signatureHex = hexUtils.concat(SignatureType.EIP1271Wallet); const expectedError = new ExchangeRevertErrors.SignatureError( ExchangeRevertErrors.SignatureErrorCode.InappropriateSignatureType, hashHex, @@ -466,7 +464,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { }; it('should revert when signerAddress == 0', async () => { - const signatureHex = hexConcat(SignatureType.EIP712); + const signatureHex = hexUtils.concat(SignatureType.EIP712); const nullMakerOrder = { ...signedOrder, makerAddress: constants.NULL_ADDRESS, @@ -486,7 +484,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { // Doesn't have to contain a real signature since our wallet contract // just does a hash comparison. const signatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(signatureDataHex, validatorWallet.address, SignatureType.Validator); + const signatureHex = hexUtils.concat(signatureDataHex, validatorWallet.address, SignatureType.Validator); const isValidSignature = await validateAsync( signedOrder, signatureHex, @@ -501,7 +499,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { // just does a hash comparison. const signatureDataHex = generateRandomSignature(); const notSignatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(notSignatureDataHex, validatorWallet.address, SignatureType.Validator); + const signatureHex = hexUtils.concat(notSignatureDataHex, validatorWallet.address, SignatureType.Validator); const isValidSignature = await validateAsync( signedOrder, signatureHex, @@ -513,7 +511,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { it('should return false when validator returns `true` and SignatureType=Validator', async () => { const signatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(signatureDataHex, validatorWallet.address, SignatureType.Validator); + const signatureHex = hexUtils.concat(signatureDataHex, validatorWallet.address, SignatureType.Validator); const isValidSignature = await validateAsync( signedOrder, signatureHex, @@ -525,7 +523,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { it('should revert when validator returns nothing and SignatureType=Validator', async () => { const signatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(signatureDataHex, validatorWallet.address, SignatureType.Validator); + const signatureHex = hexUtils.concat(signatureDataHex, validatorWallet.address, SignatureType.Validator); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const data = eip1271Data.OrderWithHash(signedOrder, orderHashHex).getABIEncodedTransactionData(); const expectedError = new ExchangeRevertErrors.EIP1271SignatureError( @@ -542,7 +540,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { // Doesn't have to contain a real signature since our wallet contract // just does a hash comparison. const signatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(signatureDataHex, validatorWallet.address, SignatureType.Validator); + const signatureHex = hexUtils.concat(signatureDataHex, validatorWallet.address, SignatureType.Validator); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const data = eip1271Data.OrderWithHash(signedOrder, orderHashHex).getABIEncodedTransactionData(); const expectedError = new ExchangeRevertErrors.EIP1271SignatureError( @@ -559,7 +557,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { // Doesn't have to contain a real signature since our wallet contract // just does a hash comparison. const signatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(signatureDataHex, validatorWallet.address, SignatureType.Validator); + const signatureHex = hexUtils.concat(signatureDataHex, validatorWallet.address, SignatureType.Validator); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const data = eip1271Data.OrderWithHash(signedOrder, orderHashHex).getABIEncodedTransactionData(); const expectedError = new ExchangeRevertErrors.EIP1271SignatureError( @@ -579,7 +577,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { .awaitTransactionSuccessAsync({ from: signedOrder.makerAddress }); // Doesn't have to contain a real signature since our wallet contract // just does a hash comparison. - const signatureHex = hexConcat(SignatureType.Validator); + const signatureHex = hexUtils.concat(SignatureType.Validator); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const expectedError = new ExchangeRevertErrors.SignatureError( ExchangeRevertErrors.SignatureErrorCode.InvalidLength, @@ -599,7 +597,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { // Doesn't have to contain a real signature since our wallet contract // just does a hash comparison. const signatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(signatureDataHex, validatorWallet.address, SignatureType.Validator); + const signatureHex = hexUtils.concat(signatureDataHex, validatorWallet.address, SignatureType.Validator); const expectedError = new ExchangeRevertErrors.SignatureValidatorNotApprovedError( signedOrder.makerAddress, validatorWallet.address, @@ -613,7 +611,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { // Doesn't have to contain a real signature since our wallet contract // just does a hash comparison. const signatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(signatureDataHex, SignatureType.EIP1271Wallet); + const signatureHex = hexUtils.concat(signatureDataHex, SignatureType.EIP1271Wallet); // Validate signature const isValidSignature = await validateAsync( signedOrder, @@ -630,7 +628,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { // just does a hash comparison. const signatureDataHex = generateRandomSignature(); const notSignatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(notSignatureDataHex, SignatureType.EIP1271Wallet); + const signatureHex = hexUtils.concat(notSignatureDataHex, SignatureType.EIP1271Wallet); // Validate signature const isValidSignature = await validateAsync( signedOrder, @@ -644,7 +642,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { it('should return false when validator returns `true` and SignatureType=EIP1271Wallet', async () => { signedOrder.makerAddress = validatorWallet.address; const signatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(signatureDataHex, SignatureType.EIP1271Wallet); + const signatureHex = hexUtils.concat(signatureDataHex, SignatureType.EIP1271Wallet); // Validate signature const isValidSignature = await validateAsync( signedOrder, @@ -658,7 +656,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { it('should revert when validator returns nothing and SignatureType=EIP1271Wallet', async () => { signedOrder.makerAddress = validatorWallet.address; const signatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(signatureDataHex, SignatureType.EIP1271Wallet); + const signatureHex = hexUtils.concat(signatureDataHex, SignatureType.EIP1271Wallet); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const data = eip1271Data.OrderWithHash(signedOrder, orderHashHex).getABIEncodedTransactionData(); const expectedError = new ExchangeRevertErrors.EIP1271SignatureError( @@ -675,7 +673,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { signedOrder.makerAddress = validatorWallet.address; // Doesn't have to contain a real signature since our wallet contract // just does a hash comparison. - const signatureHex = hexConcat(generateRandomSignature(), SignatureType.EIP1271Wallet); + const signatureHex = hexUtils.concat(generateRandomSignature(), SignatureType.EIP1271Wallet); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const data = eip1271Data.OrderWithHash(signedOrder, orderHashHex).getABIEncodedTransactionData(); const expectedError = new ExchangeRevertErrors.EIP1271SignatureError( @@ -690,7 +688,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { it('should revert when validator reverts and SignatureType=EIP1271Wallet', async () => { signedOrder.makerAddress = validatorWallet.address; - const signatureHex = hexConcat(SignatureType.EIP1271Wallet); + const signatureHex = hexUtils.concat(SignatureType.EIP1271Wallet); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const data = eip1271Data.OrderWithHash(signedOrder, orderHashHex).getABIEncodedTransactionData(); const expectedError = new ExchangeRevertErrors.EIP1271SignatureError( @@ -704,7 +702,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { }); it('should revert when signer is an EOA and SignatureType=EIP1271Wallet', async () => { - const signatureHex = hexConcat(SignatureType.EIP1271Wallet); + const signatureHex = hexUtils.concat(SignatureType.EIP1271Wallet); signedOrder.makerAddress = notSignerAddress; const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const data = eip1271Data.OrderWithHash(signedOrder, orderHashHex).getABIEncodedTransactionData(); @@ -719,7 +717,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { }); it('should revert when signer is an EOA and SignatureType=Validator', async () => { - const signatureHex = hexConcat(notSignerAddress, SignatureType.Validator); + const signatureHex = hexUtils.concat(notSignerAddress, SignatureType.Validator); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const data = eip1271Data.OrderWithHash(signedOrder, orderHashHex).getABIEncodedTransactionData(); const expectedError = new ExchangeRevertErrors.EIP1271SignatureError( @@ -766,7 +764,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { // We don't actually do anything with the transaction so we can just // fill it with random data. signedTransaction = await transactionFactory.newSignedTransactionAsync({ - data: hexRandom(TRANSACTION_DATA_LENGTH), + data: hexUtils.random(TRANSACTION_DATA_LENGTH), }); }); @@ -790,7 +788,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { }; it('should revert when signerAddress == 0', async () => { - const signatureHex = hexConcat(SignatureType.EIP712); + const signatureHex = hexUtils.concat(SignatureType.EIP712); const nullSignerTransaction = { ...signedTransaction, signerAddress: constants.NULL_ADDRESS, @@ -810,7 +808,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { // Doesn't have to contain a real signature since our wallet contract // just does a hash comparison. const signatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(signatureDataHex, validatorWallet.address, SignatureType.Validator); + const signatureHex = hexUtils.concat(signatureDataHex, validatorWallet.address, SignatureType.Validator); const isValidSignature = await validateAsync( signedTransaction, signatureHex, @@ -825,7 +823,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { // just does a hash comparison. const signatureDataHex = generateRandomSignature(); const notSignatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(notSignatureDataHex, validatorWallet.address, SignatureType.Validator); + const signatureHex = hexUtils.concat(notSignatureDataHex, validatorWallet.address, SignatureType.Validator); const isValidSignature = await validateAsync( signedTransaction, signatureHex, @@ -837,7 +835,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { it('should return false when validator returns `true` and SignatureType=Validator', async () => { const signatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(signatureDataHex, validatorWallet.address, SignatureType.Validator); + const signatureHex = hexUtils.concat(signatureDataHex, validatorWallet.address, SignatureType.Validator); const isValidSignature = await validateAsync( signedTransaction, signatureHex, @@ -854,7 +852,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { .awaitTransactionSuccessAsync({ from: signedTransaction.signerAddress }); // Doesn't have to contain a real signature since our wallet contract // just does a hash comparison. - const signatureHex = hexConcat(SignatureType.Validator); + const signatureHex = hexUtils.concat(SignatureType.Validator); const transactionHashHex = transactionHashUtils.getTransactionHashHex(signedTransaction); const expectedError = new ExchangeRevertErrors.SignatureError( ExchangeRevertErrors.SignatureErrorCode.InvalidLength, @@ -868,7 +866,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { it('should revert when validator returns nothing and SignatureType=Validator', async () => { const signatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(signatureDataHex, validatorWallet.address, SignatureType.Validator); + const signatureHex = hexUtils.concat(signatureDataHex, validatorWallet.address, SignatureType.Validator); const transactionHashHex = transactionHashUtils.getTransactionHashHex(signedTransaction); const data = eip1271Data .ZeroExTransactionWithHash(signedTransaction, transactionHashHex) @@ -892,7 +890,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { // Doesn't have to contain a real signature since our wallet contract // just does a hash comparison. const signatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(signatureDataHex, validatorWallet.address, SignatureType.Validator); + const signatureHex = hexUtils.concat(signatureDataHex, validatorWallet.address, SignatureType.Validator); const transactionHashHex = transactionHashUtils.getTransactionHashHex(signedTransaction); const data = eip1271Data .ZeroExTransactionWithHash(signedTransaction, transactionHashHex) @@ -911,7 +909,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { // Doesn't have to contain a real signature since our wallet contract // just does a hash comparison. const signatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(signatureDataHex, validatorWallet.address, SignatureType.Validator); + const signatureHex = hexUtils.concat(signatureDataHex, validatorWallet.address, SignatureType.Validator); const transactionHashHex = transactionHashUtils.getTransactionHashHex(signedTransaction); const data = eip1271Data .ZeroExTransactionWithHash(signedTransaction, transactionHashHex) @@ -934,7 +932,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { // Doesn't have to contain a real signature since our wallet contract // just does a hash comparison. const signatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(signatureDataHex, validatorWallet.address, SignatureType.Validator); + const signatureHex = hexUtils.concat(signatureDataHex, validatorWallet.address, SignatureType.Validator); const expectedError = new ExchangeRevertErrors.SignatureValidatorNotApprovedError( signedTransaction.signerAddress, validatorWallet.address, @@ -948,7 +946,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { // Doesn't have to contain a real signature since our wallet contract // just does a hash comparison. const signatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(signatureDataHex, SignatureType.EIP1271Wallet); + const signatureHex = hexUtils.concat(signatureDataHex, SignatureType.EIP1271Wallet); // Validate signature const isValidSignature = await validateAsync( signedTransaction, @@ -965,7 +963,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { // just does a hash comparison. const signatureDataHex = generateRandomSignature(); const notSignatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(notSignatureDataHex, SignatureType.EIP1271Wallet); + const signatureHex = hexUtils.concat(notSignatureDataHex, SignatureType.EIP1271Wallet); // Validate signature const isValidSignature = await validateAsync( signedTransaction, @@ -979,7 +977,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { it('should return false when validator returns `true` and SignatureType=EIP1271Wallet', async () => { signedTransaction.signerAddress = validatorWallet.address; const signatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(signatureDataHex, SignatureType.EIP1271Wallet); + const signatureHex = hexUtils.concat(signatureDataHex, SignatureType.EIP1271Wallet); // Validate signature const isValidSignature = await validateAsync( signedTransaction, @@ -993,7 +991,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { it('should revert when validator returns nothing and SignatureType=EIP1271Wallet', async () => { signedTransaction.signerAddress = validatorWallet.address; const signatureDataHex = generateRandomSignature(); - const signatureHex = hexConcat(signatureDataHex, SignatureType.EIP1271Wallet); + const signatureHex = hexUtils.concat(signatureDataHex, SignatureType.EIP1271Wallet); const transactionHashHex = transactionHashUtils.getTransactionHashHex(signedTransaction); const data = eip1271Data .ZeroExTransactionWithHash(signedTransaction, transactionHashHex) @@ -1017,7 +1015,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { signedTransaction.signerAddress = validatorWallet.address; // Doesn't have to contain a real signature since our wallet contract // just does a hash comparison. - const signatureHex = hexConcat(generateRandomSignature(), SignatureType.EIP1271Wallet); + const signatureHex = hexUtils.concat(generateRandomSignature(), SignatureType.EIP1271Wallet); const transactionHashHex = transactionHashUtils.getTransactionHashHex(signedTransaction); const data = eip1271Data .ZeroExTransactionWithHash(signedTransaction, transactionHashHex) @@ -1036,7 +1034,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { signedTransaction.signerAddress = validatorWallet.address; // Doesn't have to contain a real signature since our wallet contract // just does a hash comparison. - const signatureHex = hexConcat(generateRandomSignature(), SignatureType.EIP1271Wallet); + const signatureHex = hexUtils.concat(generateRandomSignature(), SignatureType.EIP1271Wallet); const transactionHashHex = transactionHashUtils.getTransactionHashHex(signedTransaction); const data = eip1271Data .ZeroExTransactionWithHash(signedTransaction, transactionHashHex) @@ -1052,7 +1050,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { }); it('should revert when signer is an EOA and SignatureType=EIP1271Wallet', async () => { - const signatureHex = hexConcat(SignatureType.EIP1271Wallet); + const signatureHex = hexUtils.concat(SignatureType.EIP1271Wallet); const transactionHashHex = transactionHashUtils.getTransactionHashHex(signedTransaction); const data = eip1271Data .ZeroExTransactionWithHash(signedTransaction, transactionHashHex) @@ -1068,7 +1066,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { }); it('should revert when signer is an EOA and SignatureType=Validator', async () => { - const signatureHex = hexConcat(notSignerAddress, SignatureType.Validator); + const signatureHex = hexUtils.concat(notSignerAddress, SignatureType.Validator); const transactionHashHex = transactionHashUtils.getTransactionHashHex(signedTransaction); const data = eip1271Data .ZeroExTransactionWithHash(signedTransaction, transactionHashHex) @@ -1206,7 +1204,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { }); it('should revert if `Validator` signature type rejects during a second fill', async () => { - const signatureHex = hexConcat(validatorWallet.address, SignatureType.Validator); + const signatureHex = hexUtils.concat(validatorWallet.address, SignatureType.Validator); signedOrder.signature = signatureHex; const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); // Allow the signature check for the first fill. @@ -1234,7 +1232,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { }); it('should revert if `Wallet` signature type rejects during a second fill', async () => { - const signatureHex = hexConcat(SignatureType.Wallet); + const signatureHex = hexUtils.concat(SignatureType.Wallet); signedOrder.makerAddress = validatorWallet.address; signedOrder.signature = signatureHex; const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); @@ -1263,7 +1261,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { }); it('should revert if `EIP1271Wallet` signature type rejects during a second fill', async () => { - const signatureHex = hexConcat(SignatureType.EIP1271Wallet); + const signatureHex = hexUtils.concat(SignatureType.EIP1271Wallet); signedOrder.makerAddress = validatorWallet.address; signedOrder.signature = signatureHex; const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); diff --git a/contracts/exchange/test/transactions_unit_tests.ts b/contracts/exchange/test/transactions_unit_tests.ts index f84160f422..a237bf3853 100644 --- a/contracts/exchange/test/transactions_unit_tests.ts +++ b/contracts/exchange/test/transactions_unit_tests.ts @@ -1,13 +1,6 @@ -import { - blockchainTests, - constants, - describe, - expect, - hexRandom, - transactionHashUtils, -} from '@0x/contracts-test-utils'; +import { blockchainTests, constants, describe, expect, transactionHashUtils } from '@0x/contracts-test-utils'; import { EIP712DomainWithDefaultSchema, ZeroExTransaction } from '@0x/types'; -import { BigNumber, ExchangeRevertErrors, StringRevertError } from '@0x/utils'; +import { BigNumber, ExchangeRevertErrors, hexUtils, StringRevertError } from '@0x/utils'; import { LogWithDecodedArgs } from 'ethereum-types'; import * as _ from 'lodash'; @@ -19,7 +12,7 @@ blockchainTests.resets('Transaction Unit Tests', ({ provider, web3Wrapper, txDef let accounts: string[]; let domain: EIP712DomainWithDefaultSchema; - const randomSignature = () => hexRandom(66); + const randomSignature = () => hexUtils.random(66); const EMPTY_ZERO_EX_TRANSACTION = { salt: constants.ZERO_AMOUNT, @@ -668,7 +661,7 @@ blockchainTests.resets('Transaction Unit Tests', ({ provider, web3Wrapper, txDef describe('setCurrentContextAddressIfRequired', () => { it('should set the currentContextAddress if signer not equal to sender', async () => { - const randomAddress = hexRandom(20); + const randomAddress = hexUtils.random(20); await transactionsContract .setCurrentContextAddressIfRequired(randomAddress, randomAddress) .awaitTransactionSuccessAsync(); @@ -676,7 +669,7 @@ blockchainTests.resets('Transaction Unit Tests', ({ provider, web3Wrapper, txDef expect(currentContextAddress).to.eq(randomAddress); }); it('should not set the currentContextAddress if signer equal to sender', async () => { - const randomAddress = hexRandom(20); + const randomAddress = hexUtils.random(20); await transactionsContract .setCurrentContextAddressIfRequired(accounts[0], randomAddress) .awaitTransactionSuccessAsync({ diff --git a/contracts/exchange/test/wrapper_unit_tests.ts b/contracts/exchange/test/wrapper_unit_tests.ts index b518c1d109..7b13d86769 100644 --- a/contracts/exchange/test/wrapper_unit_tests.ts +++ b/contracts/exchange/test/wrapper_unit_tests.ts @@ -6,12 +6,11 @@ import { describe, expect, getRandomPortion, - hexRandom, orderHashUtils, } from '@0x/contracts-test-utils'; import { ReferenceFunctions as UtilReferenceFunctions, SafeMathRevertErrors } from '@0x/contracts-utils'; import { FillResults, Order } from '@0x/types'; -import { AnyRevertError, BigNumber, ExchangeRevertErrors, StringRevertError } from '@0x/utils'; +import { AnyRevertError, BigNumber, ExchangeRevertErrors, hexUtils, StringRevertError } from '@0x/utils'; import { LogEntry, LogWithDecodedArgs } from 'ethereum-types'; import * as ethjs from 'ethereumjs-util'; import * as _ from 'lodash'; @@ -30,11 +29,11 @@ blockchainTests('Exchange wrapper functions unit tests.', env => { const { addFillResults, getPartialAmountCeil } = LibReferenceFunctions; const { safeSub } = UtilReferenceFunctions; const protocolFeeMultiplier = new BigNumber(150000); - const randomAddress = () => hexRandom(constants.ADDRESS_LENGTH); - const randomAssetData = () => hexRandom(34); + const randomAddress = () => hexUtils.random(constants.ADDRESS_LENGTH); + const randomAssetData = () => hexUtils.random(34); const randomAmount = (maxAmount: BigNumber = ONE_ETHER) => maxAmount.times(_.random(0, 100, true).toFixed(12)); const randomTimestamp = () => new BigNumber(Math.floor(_.now() / 1000) + _.random(0, 34560)); - const randomSalt = () => new BigNumber(hexRandom(constants.WORD_LENGTH).substr(2), 16); + const randomSalt = () => new BigNumber(hexUtils.random(constants.WORD_LENGTH).substr(2), 16); const ALWAYS_FAILING_SALT = constants.MAX_UINT256; const ALWAYS_FAILING_SALT_REVERT_ERROR = new StringRevertError('ALWAYS_FAILING_SALT'); const EMPTY_FILL_RESULTS = { @@ -1090,7 +1089,7 @@ blockchainTests('Exchange wrapper functions unit tests.', env => { takerAssetAmount: new BigNumber(20000), }), ]; - const signatures = [hexRandom()]; + const signatures = [hexUtils.random()]; const fillAmount = new BigNumber(10000); const fillResults = await roundingTestContract .marketBuyOrdersNoThrow(orders, fillAmount, signatures) @@ -1105,7 +1104,7 @@ blockchainTests('Exchange wrapper functions unit tests.', env => { takerAssetAmount: new BigNumber('6300000000000000000'), }), ]; - const signatures = [hexRandom()]; + const signatures = [hexUtils.random()]; const fillAmount = new BigNumber('2400000000000000000'); const fillResults = await roundingTestContract .marketBuyOrdersNoThrow(orders, fillAmount, signatures) @@ -1120,7 +1119,7 @@ blockchainTests('Exchange wrapper functions unit tests.', env => { takerAssetAmount: new BigNumber('103048102885858024121'), }), ]; - const signatures = [hexRandom()]; + const signatures = [hexUtils.random()]; const fillAmount = new BigNumber('84819838457312347759'); const fillResults = await roundingTestContract .marketBuyOrdersNoThrow(orders, fillAmount, signatures) @@ -1134,7 +1133,7 @@ blockchainTests('Exchange wrapper functions unit tests.', env => { it(`${i + 1}/${FUZZ_COUNT}`, async () => { const ordersCount = _.random(1, 10); const orders = _.times(ordersCount, () => randomOrder()); - const signatures = orders.map(() => hexRandom()); + const signatures = orders.map(() => hexUtils.random()); const totalMakerAssetAmount = BigNumber.sum(...orders.map(o => o.makerAssetAmount)); const fillAmount = getRandomPortion(totalMakerAssetAmount); const fillResults = await roundingTestContract diff --git a/contracts/extensions/CHANGELOG.json b/contracts/extensions/CHANGELOG.json index 09d53cd88c..804e4945e5 100644 --- a/contracts/extensions/CHANGELOG.json +++ b/contracts/extensions/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "5.1.0", + "changes": [ + { + "note": "Export function `encodeDutchAuctionAssetData`", + "pr": 2373 + } + ] + }, { "version": "5.0.0", "changes": [ diff --git a/contracts/extensions/package.json b/contracts/extensions/package.json index b16ab55905..5fdaf50b65 100644 --- a/contracts/extensions/package.json +++ b/contracts/extensions/package.json @@ -77,6 +77,8 @@ "chai-as-promised": "^7.1.0", "chai-bignumber": "^3.0.0", "dirty-chai": "^2.0.1", + "ethereumjs-abi": "0.6.5", + "ethereumjs-util": "^5.1.1", "lodash": "^4.17.11", "make-promises-safe": "^1.1.0", "mocha": "^6.2.0", diff --git a/contracts/extensions/test/dutch_auction.ts b/contracts/extensions/test/dutch_auction.ts index 1893799188..f38c1ebdd9 100644 --- a/contracts/extensions/test/dutch_auction.ts +++ b/contracts/extensions/test/dutch_auction.ts @@ -15,7 +15,7 @@ import { web3Wrapper, } from '@0x/contracts-test-utils'; import { BlockchainLifecycle } from '@0x/dev-utils'; -import { assetDataUtils, generatePseudoRandomSalt } from '@0x/order-utils'; +import { generatePseudoRandomSalt } from '@0x/order-utils'; import { RevertReason, SignedOrder } from '@0x/types'; import { BigNumber, providerUtils } from '@0x/utils'; import { Web3Wrapper } from '@0x/web3-wrapper'; @@ -26,6 +26,8 @@ import { DutchAuctionContract, DutchAuctionTestWrapper, WETH9Contract } from './ import { artifacts } from './artifacts'; +import { encodeDutchAuctionAssetData } from './utils'; + chaiSetup.configure(); const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); @@ -158,7 +160,7 @@ describe(ContractName.DutchAuction, () => { feeRecipientAddress, // taker address or sender address should be set to the ducth auction contract takerAddress: dutchAuctionContract.address, - makerAssetData: assetDataUtils.encodeDutchAuctionAssetData( + makerAssetData: encodeDutchAuctionAssetData( await devUtils.encodeERC20AssetData(defaultMakerAssetAddress).callAsync(), auctionBeginTimeSeconds, auctionBeginAmount, @@ -202,7 +204,7 @@ describe(ContractName.DutchAuction, () => { describe('matchOrders', () => { it('should be worth the begin price at the begining of the auction', async () => { auctionBeginTimeSeconds = new BigNumber(currentBlockTimestamp + 2); - const makerAssetData = assetDataUtils.encodeDutchAuctionAssetData( + const makerAssetData = encodeDutchAuctionAssetData( defaultERC20MakerAssetData, auctionBeginTimeSeconds, auctionBeginAmount, @@ -216,7 +218,7 @@ describe(ContractName.DutchAuction, () => { it('should be be worth the end price at the end of the auction', async () => { auctionBeginTimeSeconds = new BigNumber(currentBlockTimestamp - tenMinutesInSeconds * 2); auctionEndTimeSeconds = new BigNumber(currentBlockTimestamp - tenMinutesInSeconds); - const makerAssetData = assetDataUtils.encodeDutchAuctionAssetData( + const makerAssetData = encodeDutchAuctionAssetData( defaultERC20MakerAssetData, auctionBeginTimeSeconds, auctionBeginAmount, @@ -282,7 +284,7 @@ describe(ContractName.DutchAuction, () => { it('should revert when auction expires', async () => { auctionBeginTimeSeconds = new BigNumber(currentBlockTimestamp - tenMinutesInSeconds * 2); auctionEndTimeSeconds = new BigNumber(currentBlockTimestamp - tenMinutesInSeconds); - const makerAssetData = assetDataUtils.encodeDutchAuctionAssetData( + const makerAssetData = encodeDutchAuctionAssetData( defaultERC20MakerAssetData, auctionBeginTimeSeconds, auctionBeginAmount, @@ -310,7 +312,7 @@ describe(ContractName.DutchAuction, () => { }); it('begin time is less than end time', async () => { auctionBeginTimeSeconds = new BigNumber(auctionEndTimeSeconds).plus(tenMinutesInSeconds); - const makerAssetData = assetDataUtils.encodeDutchAuctionAssetData( + const makerAssetData = encodeDutchAuctionAssetData( defaultERC20MakerAssetData, auctionBeginTimeSeconds, auctionBeginAmount, @@ -336,7 +338,7 @@ describe(ContractName.DutchAuction, () => { const erc721MakerAssetData = await devUtils .encodeERC721AssetData(erc721Token.address, makerAssetId) .callAsync(); - const makerAssetData = assetDataUtils.encodeDutchAuctionAssetData( + const makerAssetData = encodeDutchAuctionAssetData( erc721MakerAssetData, auctionBeginTimeSeconds, auctionBeginAmount, diff --git a/contracts/extensions/test/utils/index.ts b/contracts/extensions/test/utils/index.ts index 6ba9a23001..f188c53b41 100644 --- a/contracts/extensions/test/utils/index.ts +++ b/contracts/extensions/test/utils/index.ts @@ -1,2 +1,23 @@ +import { BigNumber } from '@0x/utils'; +import * as ethAbi from 'ethereumjs-abi'; +import * as ethUtil from 'ethereumjs-util'; + export * from './balance_threshold_wrapper'; export * from './dutch_auction_test_wrapper'; + +// tslint:disable-next-line:completed-docs +export function encodeDutchAuctionAssetData( + assetData: string, + beginTimeSeconds: BigNumber, + beginAmount: BigNumber, +): string { + const assetDataBuffer = ethUtil.toBuffer(assetData); + const abiEncodedAuctionData = (ethAbi as any).rawEncode( + ['uint256', 'uint256'], + [beginTimeSeconds.toString(), beginAmount.toString()], + ); + const abiEncodedAuctionDataBuffer = ethUtil.toBuffer(abiEncodedAuctionData); + const dutchAuctionDataBuffer = Buffer.concat([assetDataBuffer, abiEncodedAuctionDataBuffer]); + const dutchAuctionData = ethUtil.bufferToHex(dutchAuctionDataBuffer); + return dutchAuctionData; +} diff --git a/contracts/integrations/package.json b/contracts/integrations/package.json index 43a52feae6..d8e5fd9660 100644 --- a/contracts/integrations/package.json +++ b/contracts/integrations/package.json @@ -58,7 +58,7 @@ "@0x/contracts-exchange-libs": "^4.0.0", "@0x/contracts-gen": "^2.0.0", "@0x/contracts-utils": "^4.0.0", - "@0x/coordinator-server": "^1.0.3", + "@0x/coordinator-server": "^1.0.4", "@0x/dev-utils": "^3.0.0", "@0x/migrations": "^5.0.0", "@0x/order-utils": "^9.0.0", diff --git a/contracts/integrations/test/coordinator/coordinator_test.ts b/contracts/integrations/test/coordinator/coordinator_test.ts index ec5848b474..235b464db7 100644 --- a/contracts/integrations/test/coordinator/coordinator_test.ts +++ b/contracts/integrations/test/coordinator/coordinator_test.ts @@ -11,14 +11,12 @@ import { constants, ExchangeFunctionName, expect, - hexConcat, - hexSlice, orderHashUtils, transactionHashUtils, verifyEvents, } from '@0x/contracts-test-utils'; import { SignedOrder, SignedZeroExTransaction } from '@0x/types'; -import { BigNumber } from '@0x/utils'; +import { BigNumber, hexUtils } from '@0x/utils'; import { Actor } from '../framework/actors/base'; import { FeeRecipient } from '../framework/actors/fee_recipient'; @@ -225,10 +223,10 @@ blockchainTests.resets('Coordinator integration tests', env => { return expect(tx).to.revertWith(expectedError); }); it(`${fnName} should revert with an invalid approval signature`, async () => { - const approvalSignature = hexConcat( - hexSlice(approval.signature, 0, 2), + const approvalSignature = hexUtils.concat( + hexUtils.slice(approval.signature, 0, 2), '0xFFFFFFFF', - hexSlice(approval.signature, 6), + hexUtils.slice(approval.signature, 6), ); const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); const tx = coordinator @@ -305,10 +303,10 @@ blockchainTests.resets('Coordinator integration tests', env => { verifyEvents(txReceipt, orders.map(order => expectedFillEvent(order)), ExchangeEvents.Fill); }); it(`${fnName} should revert with an invalid approval signature`, async () => { - const approvalSignature = hexConcat( - hexSlice(approval.signature, 0, 2), + const approvalSignature = hexUtils.concat( + hexUtils.slice(approval.signature, 0, 2), '0xFFFFFFFF', - hexSlice(approval.signature, 6), + hexUtils.slice(approval.signature, 6), ); const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); const tx = coordinator diff --git a/contracts/integrations/test/exchange/transaction_test.ts b/contracts/integrations/test/exchange/transaction_test.ts index fd65e85d51..2ca932e446 100644 --- a/contracts/integrations/test/exchange/transaction_test.ts +++ b/contracts/integrations/test/exchange/transaction_test.ts @@ -18,15 +18,13 @@ import { ExchangeFunctionName, expect, getLatestBlockTimestampAsync, - hexConcat, - hexRandom, orderHashUtils, randomAddress, transactionHashUtils, verifyEventsFromLogs, } from '@0x/contracts-test-utils'; import { FillResults, OrderStatus, SignatureType, SignedOrder } from '@0x/types'; -import { BigNumber } from '@0x/utils'; +import { BigNumber, hexUtils } from '@0x/utils'; import { LogWithDecodedArgs } from 'ethereum-types'; import { Actor } from '../framework/actors/base'; @@ -190,7 +188,7 @@ blockchainTests.resets('Transaction integration tests', env => { const order = await maker.signOrderAsync(); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, [order]); const transaction = await takers[0].signTransactionAsync({ data }); - transaction.signature = hexConcat(hexRandom(65), SignatureType.EthSign); + transaction.signature = hexUtils.concat(hexUtils.random(65), SignatureType.EthSign); const transactionHashHex = transactionHashUtils.getTransactionHashHex(transaction); const expectedError = new ExchangeRevertErrors.SignatureError( ExchangeRevertErrors.SignatureErrorCode.BadTransactionSignature, diff --git a/contracts/integrations/test/forwarder/bridge_test.ts b/contracts/integrations/test/forwarder/bridge_test.ts index d3216d27e7..b54c9b5552 100644 --- a/contracts/integrations/test/forwarder/bridge_test.ts +++ b/contracts/integrations/test/forwarder/bridge_test.ts @@ -1,16 +1,10 @@ import { IAssetDataContract } from '@0x/contracts-asset-proxy'; import { DummyERC721TokenContract } from '@0x/contracts-erc721'; import { ForwarderContract } from '@0x/contracts-exchange-forwarder'; -import { - blockchainTests, - constants, - getLatestBlockTimestampAsync, - hexConcat, - toBaseUnitAmount, -} from '@0x/contracts-test-utils'; +import { blockchainTests, constants, getLatestBlockTimestampAsync, toBaseUnitAmount } from '@0x/contracts-test-utils'; import { generatePseudoRandomSalt } from '@0x/order-utils'; import { SignatureType, SignedOrder } from '@0x/types'; -import { AbiEncoder, BigNumber, ExchangeForwarderRevertErrors } from '@0x/utils'; +import { AbiEncoder, BigNumber, ExchangeForwarderRevertErrors, hexUtils } from '@0x/utils'; import { deployEth2DaiBridgeAsync } from '../bridges/deploy_eth2dai_bridge'; import { deployUniswapBridgeAsync } from '../bridges/deploy_uniswap_bridge'; @@ -111,7 +105,7 @@ blockchainTests.resets('Forwarder <> ERC20Bridge integration tests', env => { takerFeeAssetData: wethAssetData, expirationTimeSeconds: new BigNumber(currentBlockTimestamp).plus(fifteenMinutesInSeconds), salt: generatePseudoRandomSalt(), - signature: hexConcat(SignatureType.Wallet), + signature: hexUtils.concat(SignatureType.Wallet), }; eth2DaiBridgeOrder = { ...orderDefaults, diff --git a/contracts/integrations/test/forwarder/forwarder_test_factory.ts b/contracts/integrations/test/forwarder/forwarder_test_factory.ts index 809255f3dd..64cb1bc520 100644 --- a/contracts/integrations/test/forwarder/forwarder_test_factory.ts +++ b/contracts/integrations/test/forwarder/forwarder_test_factory.ts @@ -1,16 +1,8 @@ import { IAssetDataContract } from '@0x/contracts-asset-proxy'; import { ForwarderContract } from '@0x/contracts-exchange-forwarder'; -import { - constants, - expect, - getPercentageOfValue, - hexSlice, - Numberish, - OrderStatus, - provider, -} from '@0x/contracts-test-utils'; +import { constants, expect, getPercentageOfValue, Numberish, OrderStatus, provider } from '@0x/contracts-test-utils'; import { AssetProxyId, OrderInfo, SignedOrder } from '@0x/types'; -import { BigNumber, RevertError } from '@0x/utils'; +import { BigNumber, hexUtils, RevertError } from '@0x/utils'; import { TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import { FeeRecipient } from '../framework/actors/fee_recipient'; @@ -37,8 +29,8 @@ interface MarketBuyOptions extends MarketSellOptions { } function areUnderlyingAssetsEqual(assetData1: string, assetData2: string): boolean { - const assetProxyId1 = hexSlice(assetData1, 0, 4); - const assetProxyId2 = hexSlice(assetData2, 0, 4); + const assetProxyId1 = hexUtils.slice(assetData1, 0, 4); + const assetProxyId2 = hexUtils.slice(assetData2, 0, 4); if ( (assetProxyId1 === AssetProxyId.ERC20 || assetProxyId1 === AssetProxyId.ERC20Bridge) && (assetProxyId2 === AssetProxyId.ERC20 || assetProxyId2 === AssetProxyId.ERC20Bridge) diff --git a/contracts/integrations/test/framework/balances/local_balance_store.ts b/contracts/integrations/test/framework/balances/local_balance_store.ts index 2828408cce..4645589b9a 100644 --- a/contracts/integrations/test/framework/balances/local_balance_store.ts +++ b/contracts/integrations/test/framework/balances/local_balance_store.ts @@ -1,8 +1,8 @@ import { IAssetDataContract } from '@0x/contracts-asset-proxy'; import { ReferenceFunctions } from '@0x/contracts-exchange-libs'; -import { constants, hexSlice, Numberish, provider } from '@0x/contracts-test-utils'; +import { constants, Numberish, provider } from '@0x/contracts-test-utils'; import { AssetProxyId, SignedOrder } from '@0x/types'; -import { BigNumber } from '@0x/utils'; +import { BigNumber, hexUtils } from '@0x/utils'; import { TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import * as _ from 'lodash'; @@ -82,7 +82,7 @@ export class LocalBalanceStore extends BalanceStore { if (fromAddress === toAddress || amount.isZero()) { return; } - const assetProxyId = hexSlice(assetData, 0, 4); + const assetProxyId = hexUtils.slice(assetData, 0, 4); switch (assetProxyId) { case AssetProxyId.ERC20: { const tokenAddress = this._assetDataDecoder.getABIDecodedTransactionData( diff --git a/contracts/multisig/test/utils/zero_ex_governor_wrapper.ts b/contracts/multisig/test/utils/zero_ex_governor_wrapper.ts index 04d3246b1c..9209c75b15 100644 --- a/contracts/multisig/test/utils/zero_ex_governor_wrapper.ts +++ b/contracts/multisig/test/utils/zero_ex_governor_wrapper.ts @@ -1,5 +1,5 @@ -import { constants, hexRandom, increaseTimeAndMineBlockAsync } from '@0x/contracts-test-utils'; -import { AbiEncoder, BigNumber } from '@0x/utils'; +import { constants, increaseTimeAndMineBlockAsync } from '@0x/contracts-test-utils'; +import { AbiEncoder, BigNumber, hexUtils } from '@0x/utils'; import { LogWithDecodedArgs, TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import * as _ from 'lodash'; @@ -22,7 +22,7 @@ export class ZeroExGovernorWrapper { const batchTransactionData = batchTransactionEncoder.encode([data, destinations, values]); const txReceipt = await this._governor .submitTransaction( - hexRandom(20), // submitTransaction will fail if this is a null address + hexUtils.random(20), // submitTransaction will fail if this is a null address constants.ZERO_AMOUNT, batchTransactionData, ) diff --git a/contracts/multisig/test/zero_ex_governor.ts b/contracts/multisig/test/zero_ex_governor.ts index 101ea49f20..1dbc71ab5d 100644 --- a/contracts/multisig/test/zero_ex_governor.ts +++ b/contracts/multisig/test/zero_ex_governor.ts @@ -1,7 +1,7 @@ -import { blockchainTests, constants, expect, getLatestBlockTimestampAsync, hexRandom } from '@0x/contracts-test-utils'; +import { blockchainTests, constants, expect, getLatestBlockTimestampAsync } from '@0x/contracts-test-utils'; import { LibBytesRevertErrors } from '@0x/contracts-utils'; import { RevertReason } from '@0x/types'; -import { BigNumber } from '@0x/utils'; +import { BigNumber, hexUtils } from '@0x/utils'; import { LogEntry, LogWithDecodedArgs } from 'ethereum-types'; import * as _ from 'lodash'; @@ -71,8 +71,8 @@ blockchainTests.resets('ZeroExGovernor', env => { functionCallTimeLockSecondsLength === undefined ? functionSelectorLength : functionCallTimeLockSecondsLength; - const functionSelectors = _.times(functionSelectorLength, () => hexRandom(4)); - const destinations = _.times(_destinationsLength, () => hexRandom(20)); + const functionSelectors = _.times(functionSelectorLength, () => hexUtils.random(4)); + const destinations = _.times(_destinationsLength, () => hexUtils.random(20)); const functionCallTimeLockSeconds = _.times(_functionCallTimeLockSecondsLength, () => BigNumber.random() // random int > 0 and < 1000 .times(10000000) @@ -395,7 +395,7 @@ blockchainTests.resets('ZeroExGovernor', env => { expect(executionLog.args.transactionId).to.bignumber.eq(txId); } it('should revert if the transaction is not confirmed by the required amount of signers', async () => { - const data = [hexRandom()]; + const data = [hexUtils.random()]; const destinations = [receiver.address]; const results = await governorWrapper.submitTransactionAsync(data, destinations, signerAddresses[0]); const tx = governor.executeTransaction(results.txId).awaitTransactionSuccessAsync({ @@ -404,7 +404,7 @@ blockchainTests.resets('ZeroExGovernor', env => { expect(tx).to.revertWith(RevertReason.TxNotFullyConfirmed); }); it('should revert if the transaction is not confirmed by the required amount of signers and called by the submitter', async () => { - const data = [hexRandom()]; + const data = [hexUtils.random()]; const destinations = [receiver.address]; const results = await governorWrapper.submitTransactionAsync(data, destinations, signerAddresses[0]); const tx = governor.executeTransaction(results.txId).awaitTransactionSuccessAsync({ @@ -413,7 +413,7 @@ blockchainTests.resets('ZeroExGovernor', env => { expect(tx).to.revertWith(RevertReason.TxNotFullyConfirmed); }); it('should be able to execute an unregistered function after the default timelock with no value', async () => { - const data = [hexRandom()]; + const data = [hexUtils.random()]; const destinations = [receiver.address]; const results = await governorWrapper.submitConfirmAndExecuteTransactionAsync( data, @@ -424,7 +424,7 @@ blockchainTests.resets('ZeroExGovernor', env => { assertReceiverCalledFromLogs(results.executionTxReceipt.logs, data, destinations, results.txId); }); it('should be able to execute an unregistered function after the default timelock with a value', async () => { - const data = [hexRandom()]; + const data = [hexUtils.random()]; const destinations = [receiver.address]; const values = [INITIAL_BALANCE]; const results = await governorWrapper.submitConfirmAndExecuteTransactionAsync( @@ -437,7 +437,7 @@ blockchainTests.resets('ZeroExGovernor', env => { assertReceiverCalledFromLogs(results.executionTxReceipt.logs, data, destinations, results.txId, values); }); it('should be able to execute a registered function after a custom timelock with no value', async () => { - const data = [hexRandom()]; + const data = [hexUtils.random()]; const destinations = [receiver.address]; const newTimeLock = new BigNumber(DEFAULT_TIME_LOCK).dividedToIntegerBy(2); await governor @@ -452,7 +452,7 @@ blockchainTests.resets('ZeroExGovernor', env => { assertReceiverCalledFromLogs(results.executionTxReceipt.logs, data, destinations, results.txId); }); it('should be able to execute a registered function with no timelock', async () => { - const data = [hexRandom()]; + const data = [hexUtils.random()]; const destinations = [receiver.address]; const newTimeLock = constants.ZERO_AMOUNT; await governor @@ -467,7 +467,7 @@ blockchainTests.resets('ZeroExGovernor', env => { assertReceiverCalledFromLogs(results.executionTxReceipt.logs, data, destinations, results.txId); }); it('should be able to execute a registered function after a custom timelock with a value', async () => { - const data = [hexRandom()]; + const data = [hexUtils.random()]; const destinations = [receiver.address]; const newTimeLock = new BigNumber(DEFAULT_TIME_LOCK).dividedToIntegerBy(2); await governor @@ -484,7 +484,7 @@ blockchainTests.resets('ZeroExGovernor', env => { assertReceiverCalledFromLogs(results.executionTxReceipt.logs, data, destinations, results.txId, values); }); it('should be able to call multiple functions with a single destination and no values', async () => { - const data = [hexRandom(), hexRandom()]; + const data = [hexUtils.random(), hexUtils.random()]; const destinations = [receiver.address, receiver.address]; const results = await governorWrapper.submitConfirmAndExecuteTransactionAsync( data, @@ -501,7 +501,7 @@ blockchainTests.resets('ZeroExGovernor', env => { env.txDefaults, {}, ); - const data = [hexRandom(), hexRandom()]; + const data = [hexUtils.random(), hexUtils.random()]; const destinations = [receiver.address, receiver2.address]; const values = [INITIAL_BALANCE.dividedToIntegerBy(4), INITIAL_BALANCE.dividedToIntegerBy(3)]; const results = await governorWrapper.submitConfirmAndExecuteTransactionAsync( @@ -514,7 +514,7 @@ blockchainTests.resets('ZeroExGovernor', env => { assertReceiverCalledFromLogs(results.executionTxReceipt.logs, data, destinations, results.txId, values); }); it('should be able to call a combination of registered and unregistered functions', async () => { - const data = [hexRandom(), hexRandom()]; + const data = [hexUtils.random(), hexUtils.random()]; const destinations = [receiver.address, receiver.address]; const newTimeLock = new BigNumber(DEFAULT_TIME_LOCK).dividedToIntegerBy(2); await governor @@ -529,7 +529,7 @@ blockchainTests.resets('ZeroExGovernor', env => { assertReceiverCalledFromLogs(results.executionTxReceipt.logs, data, destinations, results.txId); }); it('should fail if a single function has not passed the timelock', async () => { - const data = [hexRandom(), hexRandom()]; + const data = [hexUtils.random(), hexUtils.random()]; const destinations = [receiver.address, receiver.address]; const newTimeLock = new BigNumber(DEFAULT_TIME_LOCK).dividedToIntegerBy(2); await governor @@ -544,7 +544,7 @@ blockchainTests.resets('ZeroExGovernor', env => { expect(tx).to.revertWith(RevertReason.DefaultTimeLockIncomplete); }); it('should be able to execute a transaction if called by any address', async () => { - const data = [hexRandom()]; + const data = [hexUtils.random()]; const destinations = [receiver.address]; const results = await governorWrapper.submitConfirmAndExecuteTransactionAsync( data, @@ -579,7 +579,7 @@ blockchainTests.resets('ZeroExGovernor', env => { assertReceiverCalledFromLogs(results.executionTxReceipt.logs, data, destinations, results.txId); }); it('should revert if destinations.length != data.length', async () => { - const data = [hexRandom(), hexRandom()]; + const data = [hexUtils.random(), hexUtils.random()]; const destinations = [receiver.address]; const tx = governorWrapper.submitConfirmAndExecuteTransactionAsync( data, @@ -590,7 +590,7 @@ blockchainTests.resets('ZeroExGovernor', env => { expect(tx).to.revertWith(RevertReason.EqualLengthsRequired); }); it('should revert if values.length != data.length', async () => { - const data = [hexRandom()]; + const data = [hexUtils.random()]; const destinations = [receiver.address]; const values = [constants.ZERO_AMOUNT, constants.ZERO_AMOUNT]; const tx = governorWrapper.submitConfirmAndExecuteTransactionAsync( @@ -603,7 +603,7 @@ blockchainTests.resets('ZeroExGovernor', env => { expect(tx).to.revertWith(RevertReason.EqualLengthsRequired); }); it('should revert if the transaction is already executed', async () => { - const data = [hexRandom()]; + const data = [hexUtils.random()]; const destinations = [receiver.address]; const results = await governorWrapper.submitConfirmAndExecuteTransactionAsync( data, @@ -628,7 +628,7 @@ blockchainTests.resets('ZeroExGovernor', env => { }); it('should revert if the any call is unsuccessful', async () => { const alwaysRevertSelector = '0xF1F2F3F4'; - const data = [hexRandom(), alwaysRevertSelector]; + const data = [hexUtils.random(), alwaysRevertSelector]; const destinations = [receiver.address, receiver.address]; const tx = governorWrapper.submitConfirmAndExecuteTransactionAsync( data, diff --git a/contracts/staking/test/unit_tests/delegator_reward_test.ts b/contracts/staking/test/unit_tests/delegator_reward_test.ts index 45b9c3fb57..f7c3c553d3 100644 --- a/contracts/staking/test/unit_tests/delegator_reward_test.ts +++ b/contracts/staking/test/unit_tests/delegator_reward_test.ts @@ -3,13 +3,10 @@ import { constants, expect, filterLogsToArguments, - hexHash, - hexRandom, - hexSlice, Numberish, randomAddress, } from '@0x/contracts-test-utils'; -import { BigNumber } from '@0x/utils'; +import { BigNumber, hexUtils } from '@0x/utils'; import { LogEntry } from 'ethereum-types'; import { artifacts } from '../artifacts'; @@ -47,7 +44,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { async function rewardPoolAsync(opts?: Partial): Promise { const _opts = { - poolId: hexRandom(), + poolId: hexUtils.random(), operator: constants.NULL_ADDRESS, membersReward: getRandomInteger(1, toBaseUnitAmount(100)), operatorReward: getRandomInteger(1, toBaseUnitAmount(100)), @@ -79,7 +76,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { opts?: Partial, ): Promise { const _opts = { - poolId: hexRandom(), + poolId: hexUtils.random(), operator: constants.NULL_ADDRESS, membersReward: getRandomInteger(1, toBaseUnitAmount(100)), operatorReward: getRandomInteger(1, toBaseUnitAmount(100)), @@ -107,7 +104,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { // Generates a deterministic operator address given a pool ID. function poolIdToOperator(poolId: string): string { - return hexSlice(hexHash(poolId), -20); + return hexUtils.slice(hexUtils.hash(poolId), -20); } // Converts pre-split rewards to the amounts the contracts will calculate @@ -320,7 +317,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('nothing in epoch 2 for delegator delegating in epoch 1', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator, stake } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 (stake now active) // rewards paid for stake in epoch 1. @@ -330,7 +327,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('all rewards from epoch 3 for delegator delegating in epoch 1', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator, stake } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 (stake now active) await advanceEpochAsync(); // epoch 3 @@ -341,7 +338,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('all rewards from epoch 3 and 3 for delegator delegating in epoch 1', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator, stake } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 (stake now active) await advanceEpochAsync(); // epoch 3 @@ -353,7 +350,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('partial rewards from epoch 3 and 3 for delegator partially delegating in epoch 1', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator, stake: delegatorStake } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 (stake now active) await advanceEpochAsync(); // epoch 3 @@ -368,7 +365,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('has correct reward immediately after undelegating', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator, stake } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 (stake now active) await advanceEpochAsync(); // epoch 3 @@ -381,7 +378,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('has correct reward immediately after undelegating and redelegating', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator, stake } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 (stake now active) await advanceEpochAsync(); // epoch 3 @@ -395,7 +392,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('has correct reward immediately after undelegating, redelegating, and rewarding fees', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator, stake } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 (stake now active) await advanceEpochAsync(); // epoch 3 @@ -412,7 +409,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('ignores rewards paid in the same epoch the stake was first active in', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); // stake at 0 const { delegator, stake } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 (stake now active) @@ -425,7 +422,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('uses old stake for rewards paid in the same epoch extra stake is added', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); // stake at 0 const { delegator, stake: stake1 } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 (stake1 now active) @@ -453,7 +450,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('uses old stake for rewards paid in the epoch right after extra stake is added', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); // stake at 0 const { delegator, stake: stake1 } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 (stake1 now active) @@ -478,7 +475,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('computes correct rewards for 2 staggered delegators', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator: delegatorA, stake: stakeA } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 (stake A now active) const { delegator: delegatorB, stake: stakeB } = await delegateStakeAsync(poolId); @@ -501,7 +498,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('computes correct rewards for 2 staggered delegators with a 2 epoch gap between payments', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator: delegatorA, stake: stakeA } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 (stake A now active) const { delegator: delegatorB, stake: stakeB } = await delegateStakeAsync(poolId); @@ -525,7 +522,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('correct rewards for rewards with different stakes', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator, stake: delegatorStake } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 (stake now active) await advanceEpochAsync(); // epoch 3 @@ -550,7 +547,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { describe('with unfinalized rewards', async () => { it('nothing with only unfinalized rewards from epoch 2 for delegator with nothing delegated', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator, stake } = await delegateStakeAsync(poolId, { stake: 0 }); await advanceEpochAsync(); // epoch 2 await setUnfinalizedPoolRewardAsync({ poolId, membersStake: stake }); @@ -559,7 +556,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('nothing with only unfinalized rewards from epoch 2 for delegator delegating in epoch 1', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator, stake } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 await setUnfinalizedPoolRewardAsync({ poolId, membersStake: stake }); @@ -568,7 +565,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('returns unfinalized rewards from epoch 3 for delegator delegating in epoch 1', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator, stake } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 await advanceEpochAsync(); // epoch 3 @@ -581,7 +578,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('returns unfinalized rewards from epoch 4 for delegator delegating in epoch 1', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator, stake } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 await advanceEpochAsync(); // epoch 3 @@ -595,7 +592,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('returns unfinalized rewards from epoch 4 + rewards from epoch 3 for delegator delegating in epoch 1', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator, stake } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 await advanceEpochAsync(); // epoch 3 @@ -611,7 +608,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('returns unfinalized rewards from epoch 5 + rewards from epoch 3 for delegator delegating in epoch 2', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator, stake } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 await advanceEpochAsync(); // epoch 3 @@ -628,7 +625,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('returns correct rewards if unfinalized stake is different from previous rewards', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator, stake } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 await advanceEpochAsync(); // epoch 3 @@ -657,7 +654,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { describe('reward transfers', async () => { it('transfers all rewards to delegator when touching stake', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator, stake } = await delegateStakeAsync(poolId); await advanceEpochAsync(); // epoch 2 (stake now active) await advanceEpochAsync(); // epoch 3 @@ -670,7 +667,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('does not collect extra rewards from delegating more stake in the reward epoch', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const stakeResults = []; // stake stakeResults.push(await delegateStakeAsync(poolId)); @@ -693,7 +690,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('only collects rewards from staked epochs', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const stakeResults = []; // stake stakeResults.push(await delegateStakeAsync(poolId)); @@ -724,7 +721,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('two delegators can collect split rewards as soon as available', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator: delegatorA, stake: stakeA } = await delegateStakeAsync(poolId); const { delegator: delegatorB, stake: stakeB } = await delegateStakeAsync(poolId); const totalStake = BigNumber.sum(stakeA, stakeB); @@ -741,7 +738,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('delegator B collects correct rewards after delegator A finalizes', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator: delegatorA, stake: stakeA } = await delegateStakeAsync(poolId); const { delegator: delegatorB, stake: stakeB } = await delegateStakeAsync(poolId); const totalStake = BigNumber.sum(stakeA, stakeB); @@ -765,7 +762,7 @@ blockchainTests.resets('Delegator rewards unit tests', env => { }); it('delegator A and B collect correct rewards after external finalization', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); const { delegator: delegatorA, stake: stakeA } = await delegateStakeAsync(poolId); const { delegator: delegatorB, stake: stakeB } = await delegateStakeAsync(poolId); const totalStake = BigNumber.sum(stakeA, stakeB); diff --git a/contracts/staking/test/unit_tests/finalizer_test.ts b/contracts/staking/test/unit_tests/finalizer_test.ts index fd203e891d..39bf778855 100644 --- a/contracts/staking/test/unit_tests/finalizer_test.ts +++ b/contracts/staking/test/unit_tests/finalizer_test.ts @@ -3,11 +3,10 @@ import { constants, expect, filterLogsToArguments, - hexRandom, Numberish, shortZip, } from '@0x/contracts-test-utils'; -import { BigNumber, StakingRevertErrors } from '@0x/utils'; +import { BigNumber, hexUtils, StakingRevertErrors } from '@0x/utils'; import { LogEntry } from 'ethereum-types'; import * as _ from 'lodash'; @@ -34,8 +33,8 @@ blockchainTests.resets('Finalizer unit tests', env => { let testContract: TestFinalizerContract; before(async () => { - operatorRewardsReceiver = hexRandom(constants.ADDRESS_LENGTH); - membersRewardsReceiver = hexRandom(constants.ADDRESS_LENGTH); + operatorRewardsReceiver = hexUtils.random(constants.ADDRESS_LENGTH); + membersRewardsReceiver = hexUtils.random(constants.ADDRESS_LENGTH); testContract = await TestFinalizerContract.deployFrom0xArtifactAsync( artifacts.TestFinalizer, env.provider, @@ -69,7 +68,7 @@ blockchainTests.resets('Finalizer unit tests', env => { async function addActivePoolAsync(opts?: Partial): Promise { const maxAmount = toBaseUnitAmount(1e9); const _opts = { - poolId: hexRandom(), + poolId: hexUtils.random(), operatorShare: Math.floor(Math.random() * constants.PPM_DENOMINATOR) / constants.PPM_DENOMINATOR, feesCollected: getRandomInteger(0, maxAmount), membersStake: getRandomInteger(0, maxAmount), @@ -346,7 +345,7 @@ blockchainTests.resets('Finalizer unit tests', env => { describe('_finalizePool()', () => { it('does nothing if there were no pools to finalize', async () => { await testContract.endEpoch().awaitTransactionSuccessAsync(); - const poolId = hexRandom(); + const poolId = hexUtils.random(); const logs = await finalizePoolsAsync([poolId]); expect(logs).to.deep.eq([]); }); @@ -459,7 +458,7 @@ blockchainTests.resets('Finalizer unit tests', env => { }); it('rolls over leftover rewards into the next epoch', async () => { - const poolIds = _.times(3, () => hexRandom()); + const poolIds = _.times(3, () => hexUtils.random()); await Promise.all(poolIds.map(async id => addActivePoolAsync({ poolId: id }))); await testContract.endEpoch().awaitTransactionSuccessAsync(); const finalizeLogs = await finalizePoolsAsync(poolIds); @@ -496,13 +495,13 @@ blockchainTests.resets('Finalizer unit tests', env => { }; it('returns empty if epoch is 1', async () => { - const poolId = hexRandom(); + const poolId = hexUtils.random(); return assertUnfinalizedPoolRewardsAsync(poolId, ZERO_REWARDS); }); it('returns empty if pool did not earn rewards', async () => { await testContract.endEpoch().awaitTransactionSuccessAsync(); - const poolId = hexRandom(); + const poolId = hexUtils.random(); return assertUnfinalizedPoolRewardsAsync(poolId, ZERO_REWARDS); }); diff --git a/contracts/staking/test/unit_tests/lib_fixed_math_test.ts b/contracts/staking/test/unit_tests/lib_fixed_math_test.ts index ae020ebc4d..8e2c8d2d90 100644 --- a/contracts/staking/test/unit_tests/lib_fixed_math_test.ts +++ b/contracts/staking/test/unit_tests/lib_fixed_math_test.ts @@ -1,5 +1,5 @@ -import { blockchainTests, expect, hexRandom, Numberish } from '@0x/contracts-test-utils'; -import { BigNumber, FixedMathRevertErrors } from '@0x/utils'; +import { blockchainTests, expect, Numberish } from '@0x/contracts-test-utils'; +import { BigNumber, FixedMathRevertErrors, hexUtils } from '@0x/utils'; import { Decimal } from 'decimal.js'; import * as _ from 'lodash'; @@ -803,7 +803,7 @@ blockchainTests('LibFixedMath unit tests', env => { function getRandomDecimal(min: Numberish, max: Numberish): BigNumber { const range = new BigNumber(max).minus(min); - const random = fromFixed(new BigNumber(hexRandom().substr(2), 16)); + const random = fromFixed(new BigNumber(hexUtils.random().substr(2), 16)); return random.mod(range).plus(min); } diff --git a/contracts/staking/test/unit_tests/mixin_staking_pool_rewards.ts b/contracts/staking/test/unit_tests/mixin_staking_pool_rewards.ts index f0a284e459..3d001df18f 100644 --- a/contracts/staking/test/unit_tests/mixin_staking_pool_rewards.ts +++ b/contracts/staking/test/unit_tests/mixin_staking_pool_rewards.ts @@ -5,12 +5,11 @@ import { expect, getRandomInteger, getRandomPortion, - hexRandom, Numberish, randomAddress, verifyEventsFromLogs, } from '@0x/contracts-test-utils'; -import { BigNumber } from '@0x/utils'; +import { BigNumber, hexUtils } from '@0x/utils'; import { LogEntry, TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import { StoredBalance } from '../../src/types'; @@ -21,7 +20,7 @@ import { TestMixinStakingPoolRewardsContract, TestMixinStakingPoolRewardsEvents blockchainTests.resets('MixinStakingPoolRewards unit tests', env => { let testContract: TestMixinStakingPoolRewardsContract; - const POOL_ID = hexRandom(); + const POOL_ID = hexUtils.random(); const OPERATOR = randomAddress(); const OPERATOR_SHARE = getRandomInteger(1, constants.PPM_100_PERCENT); let caller: string; diff --git a/contracts/staking/test/unit_tests/protocol_fees_test.ts b/contracts/staking/test/unit_tests/protocol_fees_test.ts index f268fe6845..d36cf8f395 100644 --- a/contracts/staking/test/unit_tests/protocol_fees_test.ts +++ b/contracts/staking/test/unit_tests/protocol_fees_test.ts @@ -3,11 +3,10 @@ import { constants, expect, filterLogsToArguments, - hexRandom, Numberish, randomAddress, } from '@0x/contracts-test-utils'; -import { BigNumber, StakingRevertErrors } from '@0x/utils'; +import { BigNumber, hexUtils, StakingRevertErrors } from '@0x/utils'; import { LogEntry } from 'ethereum-types'; import * as _ from 'lodash'; @@ -56,7 +55,7 @@ blockchainTests('Protocol Fees unit tests', env => { async function createTestPoolAsync(opts?: Partial): Promise { const _opts = { - poolId: hexRandom(), + poolId: hexUtils.random(), operatorStake: getRandomInteger(minimumStake, '100e18'), membersStake: getRandomInteger(minimumStake, '100e18'), makers: _.times(2, () => randomAddress()), diff --git a/contracts/staking/test/unit_tests/stake_balances_test.ts b/contracts/staking/test/unit_tests/stake_balances_test.ts index 26b347806b..bf97830143 100644 --- a/contracts/staking/test/unit_tests/stake_balances_test.ts +++ b/contracts/staking/test/unit_tests/stake_balances_test.ts @@ -1,13 +1,6 @@ -import { - blockchainTests, - constants, - expect, - getRandomInteger, - hexRandom, - randomAddress, -} from '@0x/contracts-test-utils'; +import { blockchainTests, constants, expect, getRandomInteger, randomAddress } from '@0x/contracts-test-utils'; import { SafeMathRevertErrors } from '@0x/contracts-utils'; -import { BigNumber } from '@0x/utils'; +import { BigNumber, hexUtils } from '@0x/utils'; import { artifacts } from '../artifacts'; import { TestMixinStakeBalancesContract } from '../wrappers'; @@ -170,8 +163,8 @@ blockchainTests.resets('MixinStakeBalances unit tests', env => { describe('getStakeDelegatedToPoolByOwner()', () => { const staker = randomAddress(); const notStaker = randomAddress(); - const poolId = hexRandom(); - const notPoolId = hexRandom(); + const poolId = hexUtils.random(); + const notPoolId = hexUtils.random(); const delegatedBalance = randomStoredBalance(); before(async () => { @@ -197,8 +190,8 @@ blockchainTests.resets('MixinStakeBalances unit tests', env => { }); describe('getTotalStakeDelegatedToPool()', () => { - const poolId = hexRandom(); - const notPoolId = hexRandom(); + const poolId = hexUtils.random(); + const notPoolId = hexUtils.random(); const delegatedBalance = randomStoredBalance(); before(async () => { diff --git a/contracts/staking/test/unit_tests/stake_test.ts b/contracts/staking/test/unit_tests/stake_test.ts index a53611c6c1..9b130ac7d0 100644 --- a/contracts/staking/test/unit_tests/stake_test.ts +++ b/contracts/staking/test/unit_tests/stake_test.ts @@ -4,12 +4,10 @@ import { filterLogs, filterLogsToArguments, getRandomInteger, - hexLeftPad, - hexRandom, Numberish, shortZip, } from '@0x/contracts-test-utils'; -import { BigNumber, StakingRevertErrors } from '@0x/utils'; +import { BigNumber, hexUtils, StakingRevertErrors } from '@0x/utils'; import * as _ from 'lodash'; import { StakeStatus } from '../../src/types'; @@ -157,8 +155,8 @@ blockchainTests.resets('MixinStake unit tests', env => { describe('moveStake()', () => { const INVALID_POOL_ERROR = 'INVALID_POOL'; - const INVALID_POOL_ID = hexLeftPad(0); - const VALID_POOL_IDS = [hexRandom(), hexRandom()]; + const INVALID_POOL_ID = hexUtils.leftPad(0); + const VALID_POOL_IDS = [hexUtils.random(), hexUtils.random()]; let delegatedStakeToPoolByOwnerSlots: string[]; let delegatedStakeByPoolIdSlots: string[]; let globalDelegatedStakeSlot: string; diff --git a/contracts/staking/test/unit_tests/staking_pool_test.ts b/contracts/staking/test/unit_tests/staking_pool_test.ts index ca86db4988..7c0f8ee4bc 100644 --- a/contracts/staking/test/unit_tests/staking_pool_test.ts +++ b/contracts/staking/test/unit_tests/staking_pool_test.ts @@ -3,13 +3,10 @@ import { constants, expect, filterLogsToArguments, - hexLeftPad, - hexRandom, - toHex, verifyEventsFromLogs, } from '@0x/contracts-test-utils'; import { SafeMathRevertErrors } from '@0x/contracts-utils'; -import { BigNumber } from '@0x/utils'; +import { BigNumber, hexUtils } from '@0x/utils'; import * as _ from 'lodash'; import { StakingRevertErrors } from '../../src'; @@ -38,7 +35,7 @@ blockchainTests.resets('MixinStakingPool unit tests', env => { }); function toNextPoolId(lastPoolId: string): string { - return hexLeftPad(new BigNumber(lastPoolId.slice(2), 16).plus(1)); + return hexUtils.leftPad(new BigNumber(lastPoolId.slice(2), 16).plus(1)); } function randomOperatorShare(): number { @@ -53,7 +50,7 @@ blockchainTests.resets('MixinStakingPool unit tests', env => { async function createPoolAsync(opts?: Partial): Promise { const _opts = { - poolId: hexRandom(), + poolId: hexUtils.random(), operator, operatorShare: randomOperatorShare(), ...opts, @@ -99,7 +96,7 @@ blockchainTests.resets('MixinStakingPool unit tests', env => { }); it('fails if the next pool ID overflows', async () => { - await testContract.setLastPoolId(toHex(constants.MAX_UINT256)).awaitTransactionSuccessAsync(); + await testContract.setLastPoolId(hexUtils.toHex(constants.MAX_UINT256)).awaitTransactionSuccessAsync(); const tx = testContract.createStakingPool(randomOperatorShare(), false).awaitTransactionSuccessAsync(); const expectedError = new SafeMathRevertErrors.Uint256BinOpError( SafeMathRevertErrors.BinOpErrorCodes.AdditionOverflow, diff --git a/contracts/test-utils/CHANGELOG.json b/contracts/test-utils/CHANGELOG.json index 009f3e8898..4eed6ce4cc 100644 --- a/contracts/test-utils/CHANGELOG.json +++ b/contracts/test-utils/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "5.0.0", + "changes": [ + { + "note": "Removed `hex_utils.ts`. Moved to @0x/utils", + "pr": 2373 + } + ] + }, { "version": "4.0.0", "changes": [ @@ -63,7 +72,7 @@ "pr": 2031 }, { - "note": "Add `haxRandom()` to `hex_utils.ts`", + "note": "Add `hexRandom()` to `hex_utils.ts`", "pr": 2031 }, { diff --git a/contracts/test-utils/src/address_utils.ts b/contracts/test-utils/src/address_utils.ts index 0825d860b9..44a28b7c75 100644 --- a/contracts/test-utils/src/address_utils.ts +++ b/contracts/test-utils/src/address_utils.ts @@ -1,9 +1,10 @@ +import { hexUtils } from '@0x/utils'; + import { constants } from './constants'; -import { hexRandom } from './hex_utils'; /** * Generates a random address. */ export function randomAddress(): string { - return hexRandom(constants.ADDRESS_LENGTH); + return hexUtils.random(constants.ADDRESS_LENGTH); } diff --git a/contracts/test-utils/src/index.ts b/contracts/test-utils/src/index.ts index ea304a3afe..fcdddf484e 100644 --- a/contracts/test-utils/src/index.ts +++ b/contracts/test-utils/src/index.ts @@ -27,17 +27,6 @@ export { OrderFactory } from './order_factory'; export { bytes32Values, testCombinatoriallyWithReferenceFunc, uint256Values } from './combinatorial_utils'; export { TransactionFactory } from './transaction_factory'; export { testWithReferenceFuncAsync } from './test_with_reference'; -export { - hexConcat, - hexHash, - hexLeftPad, - hexInvert, - hexSlice, - hexRandom, - hexRightPad, - hexSize, - toHex, -} from './hex_utils'; export { BatchMatchOrder, ContractName, diff --git a/contracts/test-utils/src/order_utils.ts b/contracts/test-utils/src/order_utils.ts index f23e20314e..16cb9657b1 100644 --- a/contracts/test-utils/src/order_utils.ts +++ b/contracts/test-utils/src/order_utils.ts @@ -1,10 +1,9 @@ import { generatePseudoRandomSalt } from '@0x/order-utils'; import { Order, SignedOrder } from '@0x/types'; -import { BigNumber } from '@0x/utils'; +import { BigNumber, hexUtils } from '@0x/utils'; import * as _ from 'lodash'; import { constants } from './constants'; -import { hexHash } from './hex_utils'; import { BatchMatchOrder, CancelOrder, MatchOrder } from './types'; export const orderUtils = { @@ -59,7 +58,7 @@ export const orderUtils = { }, generatePseudoRandomOrderHash(): string { const randomBigNum = generatePseudoRandomSalt(); - const randomHash = hexHash(randomBigNum); + const randomHash = hexUtils.hash(randomBigNum); return randomHash; }, }; diff --git a/contracts/utils/test/lib_eip712.ts b/contracts/utils/test/lib_eip712.ts index 0dc1c9b53f..01b7547c23 100644 --- a/contracts/utils/test/lib_eip712.ts +++ b/contracts/utils/test/lib_eip712.ts @@ -1,6 +1,6 @@ -import { chaiSetup, constants, hexConcat, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils'; +import { chaiSetup, constants, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils'; import { BlockchainLifecycle } from '@0x/dev-utils'; -import { BigNumber, signTypedDataUtils } from '@0x/utils'; +import { BigNumber, hexUtils, signTypedDataUtils } from '@0x/utils'; import * as chai from 'chai'; import * as ethUtil from 'ethereumjs-util'; import * as _ from 'lodash'; @@ -48,7 +48,7 @@ describe('LibEIP712', () => { const actualHash = await lib .externalHashEIP712DomainSeperator(name, version, new BigNumber(chainId), verifyingContract) .callAsync(); - expect(actualHash).to.be.eq(hexConcat(expectedHash)); + expect(actualHash).to.be.eq(hexUtils.concat(expectedHash)); } describe('_hashEIP712Domain', async () => { diff --git a/contracts/utils/test/lib_rich_errors.ts b/contracts/utils/test/lib_rich_errors.ts index d63fe8a959..e610472fcd 100644 --- a/contracts/utils/test/lib_rich_errors.ts +++ b/contracts/utils/test/lib_rich_errors.ts @@ -1,5 +1,5 @@ -import { blockchainTests, expect, hexRandom } from '@0x/contracts-test-utils'; -import { coerceThrownErrorAsRevertError, StringRevertError } from '@0x/utils'; +import { blockchainTests, expect } from '@0x/contracts-test-utils'; +import { coerceThrownErrorAsRevertError, hexUtils, StringRevertError } from '@0x/utils'; import { artifacts } from './artifacts'; import { TestLibRichErrorsContract } from './wrappers'; @@ -19,7 +19,7 @@ blockchainTests('LibRichErrors', env => { describe('_rrevert', () => { it('should correctly revert the extra bytes', async () => { - const extraBytes = hexRandom(100); + const extraBytes = hexUtils.random(100); try { await lib.externalRRevert(extraBytes).callAsync(); } catch (err) { diff --git a/packages/0x.js/src/index.ts b/packages/0x.js/src/index.ts index f5ff0433b9..2b2c24dae1 100644 --- a/packages/0x.js/src/index.ts +++ b/packages/0x.js/src/index.ts @@ -1,6 +1,6 @@ export { getContractAddressesForChainOrThrow, ChainId, ContractAddresses } from '@0x/contract-addresses'; -export { assetDataUtils, signatureUtils, generatePseudoRandomSalt } from '@0x/order-utils'; +export { signatureUtils, generatePseudoRandomSalt, decodeAssetDataOrThrow } from '@0x/order-utils'; export { ExchangeEventArgs, @@ -60,14 +60,15 @@ export { Order, SignedOrder, ECSignature, - AssetProxyId, + AssetData, SingleAssetData, ERC20AssetData, + ERC20BridgeAssetData, ERC721AssetData, ERC1155AssetData, MultiAssetData, - MultiAssetDataWithRecursiveDecoding, StaticCallAssetData, + MultiAssetDataWithRecursiveDecoding, SignatureType, ZeroExTransaction, SignedZeroExTransaction, diff --git a/packages/asset-swapper/test/order_prune_utils_test.ts b/packages/asset-swapper/test/order_prune_utils_test.ts index dea927eaf6..5bf26004e6 100644 --- a/packages/asset-swapper/test/order_prune_utils_test.ts +++ b/packages/asset-swapper/test/order_prune_utils_test.ts @@ -3,7 +3,6 @@ import { DevUtilsContract, ERC20TokenContract, ExchangeContract } from '@0x/cont import { constants as devConstants, getLatestBlockTimestampAsync, OrderFactory } from '@0x/contracts-test-utils'; import { BlockchainLifecycle, tokenUtils } from '@0x/dev-utils'; import { migrateOnceAsync } from '@0x/migrations'; -import { assetDataUtils } from '@0x/order-utils'; import { SignedOrder } from '@0x/types'; import { BigNumber } from '@0x/utils'; import * as chai from 'chai'; @@ -70,13 +69,15 @@ describe('OrderPruner', () => { [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); erc20MakerTokenContract = new ERC20TokenContract(makerTokenAddress, provider); erc20TakerTokenContract = new ERC20TokenContract(takerTokenAddress, provider); - [makerAssetData, takerAssetData, wethAssetData] = [ - assetDataUtils.encodeERC20AssetData(makerTokenAddress), - assetDataUtils.encodeERC20AssetData(takerTokenAddress), - assetDataUtils.encodeERC20AssetData(contractAddresses.etherToken), - ]; exchangeContract = new ExchangeContract(contractAddresses.exchange, provider); devUtilsContract = new DevUtilsContract(contractAddresses.devUtils, provider); + + [makerAssetData, takerAssetData, wethAssetData] = [ + await devUtilsContract.encodeERC20AssetData(makerTokenAddress).callAsync(), + await devUtilsContract.encodeERC20AssetData(takerTokenAddress).callAsync(), + await devUtilsContract.encodeERC20AssetData(contractAddresses.etherToken).callAsync(), + ]; + // Configure order defaults const defaultOrderParams = { ...devConstants.STATIC_ORDER_PARAMS, diff --git a/packages/contract-artifacts/CHANGELOG.json b/packages/contract-artifacts/CHANGELOG.json index f6cb552521..1b5b3d367f 100644 --- a/packages/contract-artifacts/CHANGELOG.json +++ b/packages/contract-artifacts/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "3.1.0", + "changes": [ + { + "note": "Add `IAssetData` artifact", + "pr": 2373 + } + ] + }, { "version": "3.0.0", "changes": [ diff --git a/packages/contract-artifacts/artifacts/IAssetData.json b/packages/contract-artifacts/artifacts/IAssetData.json new file mode 100644 index 0000000000..01cef4c2ae --- /dev/null +++ b/packages/contract-artifacts/artifacts/IAssetData.json @@ -0,0 +1,251 @@ +{ + "schemaVersion": "2.0.0", + "contractName": "IAssetData", + "compilerOutput": { + "abi": [ + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "tokenIds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "callbackData", + "type": "bytes" + } + ], + "name": "ERC1155Assets", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "bridgeData", + "type": "bytes" + } + ], + "name": "ERC20Bridge", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "name": "ERC20Token", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ERC721Token", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "nestedAssetData", + "type": "bytes[]" + } + ], + "name": "MultiAsset", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "staticCallTargetAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "staticCallData", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "expectedReturnDataHash", + "type": "bytes32" + } + ], + "name": "StaticCall", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + ], + "devdoc": { + "methods": { + "ERC1155Assets(address,uint256[],uint256[],bytes)": { + "details": "Function signature for encoding ERC1155 assetData.", + "params": { + "callbackData": "Extra data to be passed to receiver's `onERC1155Received` callback function.", + "tokenAddress": "Address of ERC1155 token contract.", + "tokenIds": "Array of ids of tokens to be transferred.", + "values": "Array of values that correspond to each token id to be transferred. Note that each value will be multiplied by the amount being filled in the order before transferring." + } + }, + "ERC20Bridge(address,address,bytes)": { + "details": "Function signature for encoding ERC20Bridge assetData.", + "params": { + "bridgeAddress": "Address of the bridge contract.", + "bridgeData": "Arbitrary data to be passed to the bridge contract.", + "tokenAddress": "Address of token to transfer." + } + }, + "ERC20Token(address)": { + "details": "Function signature for encoding ERC20 assetData.", + "params": { + "tokenAddress": "Address of ERC20Token contract." + } + }, + "ERC721Token(address,uint256)": { + "details": "Function signature for encoding ERC721 assetData.", + "params": { + "tokenAddress": "Address of ERC721 token contract.", + "tokenId": "Id of ERC721 token to be transferred." + } + }, + "MultiAsset(uint256[],bytes[])": { + "details": "Function signature for encoding MultiAsset assetData.", + "params": { + "nestedAssetData": "Array of assetData fields that will be be dispatched to their correspnding AssetProxy contract.", + "values": "Array of amounts that correspond to each asset to be transferred. Note that each value will be multiplied by the amount being filled in the order before transferring." + } + }, + "StaticCall(address,bytes,bytes32)": { + "details": "Function signature for encoding StaticCall assetData.", + "params": { + "expectedReturnDataHash": "Keccak-256 hash of the expected staticcall return data.", + "staticCallData": "Data that will be executed via staticcall on the staticCallTargetAddress.", + "staticCallTargetAddress": "Address that will execute the staticcall." + } + } + } + }, + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "0x", + "opcodes": "", + "sourceMap": "" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "0x", + "opcodes": "", + "sourceMap": "" + } + } + }, + "sources": { + "src/interfaces/IAssetData.sol": { + "id": 11 + } + }, + "sourceCodes": { + "src/interfaces/IAssetData.sol": "/*\n\n Copyright 2019 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\n// solhint-disable\npragma solidity ^0.5.9;\npragma experimental ABIEncoderV2;\n\n\n// @dev Interface of the asset proxy's assetData.\n// The asset proxies take an ABI encoded `bytes assetData` as argument.\n// This argument is ABI encoded as one of the methods of this interface.\ninterface IAssetData {\n\n /// @dev Function signature for encoding ERC20 assetData.\n /// @param tokenAddress Address of ERC20Token contract.\n function ERC20Token(address tokenAddress)\n external;\n\n /// @dev Function signature for encoding ERC721 assetData.\n /// @param tokenAddress Address of ERC721 token contract.\n /// @param tokenId Id of ERC721 token to be transferred.\n function ERC721Token(\n address tokenAddress,\n uint256 tokenId\n )\n external;\n\n /// @dev Function signature for encoding ERC1155 assetData.\n /// @param tokenAddress Address of ERC1155 token contract.\n /// @param tokenIds Array of ids of tokens to be transferred.\n /// @param values Array of values that correspond to each token id to be transferred.\n /// Note that each value will be multiplied by the amount being filled in the order before transferring.\n /// @param callbackData Extra data to be passed to receiver's `onERC1155Received` callback function.\n function ERC1155Assets(\n address tokenAddress,\n uint256[] calldata tokenIds,\n uint256[] calldata values,\n bytes calldata callbackData\n )\n external;\n\n /// @dev Function signature for encoding MultiAsset assetData.\n /// @param values Array of amounts that correspond to each asset to be transferred.\n /// Note that each value will be multiplied by the amount being filled in the order before transferring.\n /// @param nestedAssetData Array of assetData fields that will be be dispatched to their correspnding AssetProxy contract.\n function MultiAsset(\n uint256[] calldata values,\n bytes[] calldata nestedAssetData\n )\n external;\n\n /// @dev Function signature for encoding StaticCall assetData.\n /// @param staticCallTargetAddress Address that will execute the staticcall.\n /// @param staticCallData Data that will be executed via staticcall on the staticCallTargetAddress.\n /// @param expectedReturnDataHash Keccak-256 hash of the expected staticcall return data.\n function StaticCall(\n address staticCallTargetAddress,\n bytes calldata staticCallData,\n bytes32 expectedReturnDataHash\n )\n external;\n\n /// @dev Function signature for encoding ERC20Bridge assetData.\n /// @param tokenAddress Address of token to transfer.\n /// @param bridgeAddress Address of the bridge contract.\n /// @param bridgeData Arbitrary data to be passed to the bridge contract.\n function ERC20Bridge(\n address tokenAddress,\n address bridgeAddress,\n bytes calldata bridgeData\n )\n external;\n}\n" + }, + "sourceTreeHashHex": "0x3ceff1522c201d446ee98d9ecd912ad2ca6adc6fae9fc10d458ff557d570decc", + "compiler": { + "name": "solc", + "version": "soljson-v0.5.13+commit.5b0b510c.js", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000, + "details": { + "yul": true, + "deduplicate": true, + "cse": true, + "constantOptimizer": true + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "devdoc", + "evm.bytecode.object", + "evm.bytecode.sourceMap", + "evm.deployedBytecode.object", + "evm.deployedBytecode.sourceMap" + ] + } + }, + "evmVersion": "constantinople", + "remappings": [ + "@0x/contracts-utils=/Users/xianny/src/copy-0x-monorepo/contracts/asset-proxy/node_modules/@0x/contracts-utils", + "@0x/contracts-erc1155=/Users/xianny/src/copy-0x-monorepo/contracts/asset-proxy/node_modules/@0x/contracts-erc1155", + "@0x/contracts-erc20=/Users/xianny/src/copy-0x-monorepo/contracts/asset-proxy/node_modules/@0x/contracts-erc20", + "@0x/contracts-exchange-libs=/Users/xianny/src/copy-0x-monorepo/node_modules/@0x/contracts-exchange-libs" + ] + } + }, + "chains": {} +} diff --git a/packages/contract-wrappers/CHANGELOG.json b/packages/contract-wrappers/CHANGELOG.json index 43da66f831..dd6708d981 100644 --- a/packages/contract-wrappers/CHANGELOG.json +++ b/packages/contract-wrappers/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "13.1.0", + "changes": [ + { + "note": "Add wrapper for `IAssetDataContract`", + "pr": 2373 + } + ] + }, { "version": "13.0.0", "changes": [ diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json index 67c053ff5d..73045844ca 100644 --- a/packages/contract-wrappers/package.json +++ b/packages/contract-wrappers/package.json @@ -31,7 +31,7 @@ "wrappers:generate": "abi-gen --abis ${npm_package_config_abis} --output src/generated-wrappers --backend ethers" }, "config": { - "abis": "../contract-artifacts/artifacts/@(DevUtils|ERC20Token|ERC721Token|Exchange|Forwarder|WETH9|Coordinator|Staking|StakingProxy).json" + "abis": "../contract-artifacts/artifacts/@(DevUtils|ERC20Token|ERC721Token|Exchange|Forwarder|IAssetData|WETH9|Coordinator|Staking|StakingProxy).json" }, "repository": { "type": "git", diff --git a/packages/contract-wrappers/src/generated-wrappers/i_asset_data.ts b/packages/contract-wrappers/src/generated-wrappers/i_asset_data.ts new file mode 100644 index 0000000000..0c32c00c5f --- /dev/null +++ b/packages/contract-wrappers/src/generated-wrappers/i_asset_data.ts @@ -0,0 +1,643 @@ +// tslint:disable:no-consecutive-blank-lines ordered-imports align trailing-comma enum-naming +// tslint:disable:whitespace no-unbound-method no-trailing-whitespace +// tslint:disable:no-unused-variable +import { + AwaitTransactionSuccessOpts, + ContractFunctionObj, + ContractTxFunctionObj, + SendTransactionOpts, + BaseContract, + PromiseWithTransactionHash, + methodAbiToFunctionSignature, +} from '@0x/base-contract'; +import { schemas } from '@0x/json-schemas'; +import { + BlockParam, + BlockParamLiteral, + BlockRange, + CallData, + ContractAbi, + ContractArtifact, + DecodedLogArgs, + MethodAbi, + TransactionReceiptWithDecodedLogs, + TxData, + TxDataPayable, + SupportedProvider, +} from 'ethereum-types'; +import { BigNumber, classUtils, logUtils, providerUtils } from '@0x/utils'; +import { EventCallback, IndexedFilterValues, SimpleContractArtifact } from '@0x/types'; +import { Web3Wrapper } from '@0x/web3-wrapper'; +import { assert } from '@0x/assert'; +import * as ethers from 'ethers'; +// tslint:enable:no-unused-variable + +/* istanbul ignore next */ +// tslint:disable:no-parameter-reassignment +// tslint:disable-next-line:class-name +export class IAssetDataContract extends BaseContract { + /** + * @ignore + */ + public static deployedBytecode: string | undefined; + private readonly _methodABIIndex: { [name: string]: number } = {}; + public static async deployFrom0xArtifactAsync( + artifact: ContractArtifact | SimpleContractArtifact, + supportedProvider: SupportedProvider, + txDefaults: Partial, + logDecodeDependencies: { [contractName: string]: ContractArtifact | SimpleContractArtifact }, + ): Promise { + assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [ + schemas.addressSchema, + schemas.numberSchema, + schemas.jsNumber, + ]); + if (artifact.compilerOutput === undefined) { + throw new Error('Compiler output not found in the artifact file'); + } + const provider = providerUtils.standardizeOrThrow(supportedProvider); + const bytecode = artifact.compilerOutput.evm.bytecode.object; + const abi = artifact.compilerOutput.abi; + const logDecodeDependenciesAbiOnly: { [contractName: string]: ContractAbi } = {}; + if (Object.keys(logDecodeDependencies) !== undefined) { + for (const key of Object.keys(logDecodeDependencies)) { + logDecodeDependenciesAbiOnly[key] = logDecodeDependencies[key].compilerOutput.abi; + } + } + return IAssetDataContract.deployAsync(bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly); + } + public static async deployAsync( + bytecode: string, + abi: ContractAbi, + supportedProvider: SupportedProvider, + txDefaults: Partial, + logDecodeDependencies: { [contractName: string]: ContractAbi }, + ): Promise { + assert.isHexString('bytecode', bytecode); + assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [ + schemas.addressSchema, + schemas.numberSchema, + schemas.jsNumber, + ]); + const provider = providerUtils.standardizeOrThrow(supportedProvider); + const constructorAbi = BaseContract._lookupConstructorAbi(abi); + [] = BaseContract._formatABIDataItemList(constructorAbi.inputs, [], BaseContract._bigNumberToString); + const iface = new ethers.utils.Interface(abi); + const deployInfo = iface.deployFunction; + const txData = deployInfo.encode(bytecode, []); + const web3Wrapper = new Web3Wrapper(provider); + const txDataWithDefaults = await BaseContract._applyDefaultsToContractTxDataAsync( + { + data: txData, + ...txDefaults, + }, + web3Wrapper.estimateGasAsync.bind(web3Wrapper), + ); + const txHash = await web3Wrapper.sendTransactionAsync(txDataWithDefaults); + logUtils.log(`transactionHash: ${txHash}`); + const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash); + logUtils.log(`IAssetData successfully deployed at ${txReceipt.contractAddress}`); + const contractInstance = new IAssetDataContract( + txReceipt.contractAddress as string, + provider, + txDefaults, + logDecodeDependencies, + ); + contractInstance.constructorArgs = []; + return contractInstance; + } + + /** + * @returns The contract ABI + */ + public static ABI(): ContractAbi { + const abi = [ + { + constant: false, + inputs: [ + { + name: 'tokenAddress', + type: 'address', + }, + { + name: 'tokenIds', + type: 'uint256[]', + }, + { + name: 'values', + type: 'uint256[]', + }, + { + name: 'callbackData', + type: 'bytes', + }, + ], + name: 'ERC1155Assets', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + name: 'tokenAddress', + type: 'address', + }, + { + name: 'bridgeAddress', + type: 'address', + }, + { + name: 'bridgeData', + type: 'bytes', + }, + ], + name: 'ERC20Bridge', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + name: 'tokenAddress', + type: 'address', + }, + ], + name: 'ERC20Token', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + name: 'tokenAddress', + type: 'address', + }, + { + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'ERC721Token', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + name: 'values', + type: 'uint256[]', + }, + { + name: 'nestedAssetData', + type: 'bytes[]', + }, + ], + name: 'MultiAsset', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + name: 'staticCallTargetAddress', + type: 'address', + }, + { + name: 'staticCallData', + type: 'bytes', + }, + { + name: 'expectedReturnDataHash', + type: 'bytes32', + }, + ], + name: 'StaticCall', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ] as ContractAbi; + return abi; + } + + public getFunctionSignature(methodName: string): string { + const index = this._methodABIIndex[methodName]; + const methodAbi = IAssetDataContract.ABI()[index] as MethodAbi; // tslint:disable-line:no-unnecessary-type-assertion + const functionSignature = methodAbiToFunctionSignature(methodAbi); + return functionSignature; + } + public getABIDecodedTransactionData(methodName: string, callData: string): T { + const functionSignature = this.getFunctionSignature(methodName); + const self = (this as any) as IAssetDataContract; + const abiEncoder = self._lookupAbiEncoder(functionSignature); + const abiDecodedCallData = abiEncoder.strictDecode(callData); + return abiDecodedCallData; + } + public getABIDecodedReturnData(methodName: string, callData: string): T { + const functionSignature = this.getFunctionSignature(methodName); + const self = (this as any) as IAssetDataContract; + const abiEncoder = self._lookupAbiEncoder(functionSignature); + const abiDecodedCallData = abiEncoder.strictDecodeReturnValue(callData); + return abiDecodedCallData; + } + public getSelector(methodName: string): string { + const functionSignature = this.getFunctionSignature(methodName); + const self = (this as any) as IAssetDataContract; + const abiEncoder = self._lookupAbiEncoder(functionSignature); + return abiEncoder.getSelector(); + } + + /** + * Function signature for encoding ERC1155 assetData. + * @param tokenAddress Address of ERC1155 token contract. + * @param tokenIds Array of ids of tokens to be transferred. + * @param values Array of values that correspond to each token id to be + * transferred. Note that each value will be multiplied by the + * amount being filled in the order before transferring. + * @param callbackData Extra data to be passed to receiver's + * `onERC1155Received` callback function. + */ + public ERC1155Assets( + tokenAddress: string, + tokenIds: BigNumber[], + values: BigNumber[], + callbackData: string, + ): ContractTxFunctionObj { + const self = (this as any) as IAssetDataContract; + assert.isString('tokenAddress', tokenAddress); + assert.isArray('tokenIds', tokenIds); + assert.isArray('values', values); + assert.isString('callbackData', callbackData); + const functionSignature = 'ERC1155Assets(address,uint256[],uint256[],bytes)'; + + return { + async sendTransactionAsync( + txData?: Partial | undefined, + opts: SendTransactionOpts = { shouldValidate: true }, + ): Promise { + const txDataWithDefaults = await self._applyDefaultsToTxDataAsync( + { ...txData, data: this.getABIEncodedTransactionData() }, + this.estimateGasAsync.bind(this), + ); + if (opts.shouldValidate !== false) { + await this.callAsync(txDataWithDefaults); + } + return self._web3Wrapper.sendTransactionAsync(txDataWithDefaults); + }, + awaitTransactionSuccessAsync( + txData?: Partial, + opts: AwaitTransactionSuccessOpts = { shouldValidate: true }, + ): PromiseWithTransactionHash { + return self._promiseWithTransactionHash(this.sendTransactionAsync(txData, opts), opts); + }, + async estimateGasAsync(txData?: Partial | undefined): Promise { + const txDataWithDefaults = await self._applyDefaultsToTxDataAsync({ + ...txData, + data: this.getABIEncodedTransactionData(), + }); + return self._web3Wrapper.estimateGasAsync(txDataWithDefaults); + }, + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + BaseContract._assertCallParams(callData, defaultBlock); + const rawCallResult = await self._performCallAsync( + { ...callData, data: this.getABIEncodedTransactionData() }, + defaultBlock, + ); + const abiEncoder = self._lookupAbiEncoder(functionSignature); + return abiEncoder.strictDecodeReturnValue(rawCallResult); + }, + getABIEncodedTransactionData(): string { + return self._strictEncodeArguments(functionSignature, [ + tokenAddress.toLowerCase(), + tokenIds, + values, + callbackData, + ]); + }, + }; + } + /** + * Function signature for encoding ERC20Bridge assetData. + * @param tokenAddress Address of token to transfer. + * @param bridgeAddress Address of the bridge contract. + * @param bridgeData Arbitrary data to be passed to the bridge contract. + */ + public ERC20Bridge(tokenAddress: string, bridgeAddress: string, bridgeData: string): ContractTxFunctionObj { + const self = (this as any) as IAssetDataContract; + assert.isString('tokenAddress', tokenAddress); + assert.isString('bridgeAddress', bridgeAddress); + assert.isString('bridgeData', bridgeData); + const functionSignature = 'ERC20Bridge(address,address,bytes)'; + + return { + async sendTransactionAsync( + txData?: Partial | undefined, + opts: SendTransactionOpts = { shouldValidate: true }, + ): Promise { + const txDataWithDefaults = await self._applyDefaultsToTxDataAsync( + { ...txData, data: this.getABIEncodedTransactionData() }, + this.estimateGasAsync.bind(this), + ); + if (opts.shouldValidate !== false) { + await this.callAsync(txDataWithDefaults); + } + return self._web3Wrapper.sendTransactionAsync(txDataWithDefaults); + }, + awaitTransactionSuccessAsync( + txData?: Partial, + opts: AwaitTransactionSuccessOpts = { shouldValidate: true }, + ): PromiseWithTransactionHash { + return self._promiseWithTransactionHash(this.sendTransactionAsync(txData, opts), opts); + }, + async estimateGasAsync(txData?: Partial | undefined): Promise { + const txDataWithDefaults = await self._applyDefaultsToTxDataAsync({ + ...txData, + data: this.getABIEncodedTransactionData(), + }); + return self._web3Wrapper.estimateGasAsync(txDataWithDefaults); + }, + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + BaseContract._assertCallParams(callData, defaultBlock); + const rawCallResult = await self._performCallAsync( + { ...callData, data: this.getABIEncodedTransactionData() }, + defaultBlock, + ); + const abiEncoder = self._lookupAbiEncoder(functionSignature); + return abiEncoder.strictDecodeReturnValue(rawCallResult); + }, + getABIEncodedTransactionData(): string { + return self._strictEncodeArguments(functionSignature, [ + tokenAddress.toLowerCase(), + bridgeAddress.toLowerCase(), + bridgeData, + ]); + }, + }; + } + /** + * Function signature for encoding ERC20 assetData. + * @param tokenAddress Address of ERC20Token contract. + */ + public ERC20Token(tokenAddress: string): ContractTxFunctionObj { + const self = (this as any) as IAssetDataContract; + assert.isString('tokenAddress', tokenAddress); + const functionSignature = 'ERC20Token(address)'; + + return { + async sendTransactionAsync( + txData?: Partial | undefined, + opts: SendTransactionOpts = { shouldValidate: true }, + ): Promise { + const txDataWithDefaults = await self._applyDefaultsToTxDataAsync( + { ...txData, data: this.getABIEncodedTransactionData() }, + this.estimateGasAsync.bind(this), + ); + if (opts.shouldValidate !== false) { + await this.callAsync(txDataWithDefaults); + } + return self._web3Wrapper.sendTransactionAsync(txDataWithDefaults); + }, + awaitTransactionSuccessAsync( + txData?: Partial, + opts: AwaitTransactionSuccessOpts = { shouldValidate: true }, + ): PromiseWithTransactionHash { + return self._promiseWithTransactionHash(this.sendTransactionAsync(txData, opts), opts); + }, + async estimateGasAsync(txData?: Partial | undefined): Promise { + const txDataWithDefaults = await self._applyDefaultsToTxDataAsync({ + ...txData, + data: this.getABIEncodedTransactionData(), + }); + return self._web3Wrapper.estimateGasAsync(txDataWithDefaults); + }, + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + BaseContract._assertCallParams(callData, defaultBlock); + const rawCallResult = await self._performCallAsync( + { ...callData, data: this.getABIEncodedTransactionData() }, + defaultBlock, + ); + const abiEncoder = self._lookupAbiEncoder(functionSignature); + return abiEncoder.strictDecodeReturnValue(rawCallResult); + }, + getABIEncodedTransactionData(): string { + return self._strictEncodeArguments(functionSignature, [tokenAddress.toLowerCase()]); + }, + }; + } + /** + * Function signature for encoding ERC721 assetData. + * @param tokenAddress Address of ERC721 token contract. + * @param tokenId Id of ERC721 token to be transferred. + */ + public ERC721Token(tokenAddress: string, tokenId: BigNumber): ContractTxFunctionObj { + const self = (this as any) as IAssetDataContract; + assert.isString('tokenAddress', tokenAddress); + assert.isBigNumber('tokenId', tokenId); + const functionSignature = 'ERC721Token(address,uint256)'; + + return { + async sendTransactionAsync( + txData?: Partial | undefined, + opts: SendTransactionOpts = { shouldValidate: true }, + ): Promise { + const txDataWithDefaults = await self._applyDefaultsToTxDataAsync( + { ...txData, data: this.getABIEncodedTransactionData() }, + this.estimateGasAsync.bind(this), + ); + if (opts.shouldValidate !== false) { + await this.callAsync(txDataWithDefaults); + } + return self._web3Wrapper.sendTransactionAsync(txDataWithDefaults); + }, + awaitTransactionSuccessAsync( + txData?: Partial, + opts: AwaitTransactionSuccessOpts = { shouldValidate: true }, + ): PromiseWithTransactionHash { + return self._promiseWithTransactionHash(this.sendTransactionAsync(txData, opts), opts); + }, + async estimateGasAsync(txData?: Partial | undefined): Promise { + const txDataWithDefaults = await self._applyDefaultsToTxDataAsync({ + ...txData, + data: this.getABIEncodedTransactionData(), + }); + return self._web3Wrapper.estimateGasAsync(txDataWithDefaults); + }, + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + BaseContract._assertCallParams(callData, defaultBlock); + const rawCallResult = await self._performCallAsync( + { ...callData, data: this.getABIEncodedTransactionData() }, + defaultBlock, + ); + const abiEncoder = self._lookupAbiEncoder(functionSignature); + return abiEncoder.strictDecodeReturnValue(rawCallResult); + }, + getABIEncodedTransactionData(): string { + return self._strictEncodeArguments(functionSignature, [tokenAddress.toLowerCase(), tokenId]); + }, + }; + } + /** + * Function signature for encoding MultiAsset assetData. + * @param values Array of amounts that correspond to each asset to be + * transferred. Note that each value will be multiplied by the + * amount being filled in the order before transferring. + * @param nestedAssetData Array of assetData fields that will be be dispatched + * to their correspnding AssetProxy contract. + */ + public MultiAsset(values: BigNumber[], nestedAssetData: string[]): ContractTxFunctionObj { + const self = (this as any) as IAssetDataContract; + assert.isArray('values', values); + assert.isArray('nestedAssetData', nestedAssetData); + const functionSignature = 'MultiAsset(uint256[],bytes[])'; + + return { + async sendTransactionAsync( + txData?: Partial | undefined, + opts: SendTransactionOpts = { shouldValidate: true }, + ): Promise { + const txDataWithDefaults = await self._applyDefaultsToTxDataAsync( + { ...txData, data: this.getABIEncodedTransactionData() }, + this.estimateGasAsync.bind(this), + ); + if (opts.shouldValidate !== false) { + await this.callAsync(txDataWithDefaults); + } + return self._web3Wrapper.sendTransactionAsync(txDataWithDefaults); + }, + awaitTransactionSuccessAsync( + txData?: Partial, + opts: AwaitTransactionSuccessOpts = { shouldValidate: true }, + ): PromiseWithTransactionHash { + return self._promiseWithTransactionHash(this.sendTransactionAsync(txData, opts), opts); + }, + async estimateGasAsync(txData?: Partial | undefined): Promise { + const txDataWithDefaults = await self._applyDefaultsToTxDataAsync({ + ...txData, + data: this.getABIEncodedTransactionData(), + }); + return self._web3Wrapper.estimateGasAsync(txDataWithDefaults); + }, + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + BaseContract._assertCallParams(callData, defaultBlock); + const rawCallResult = await self._performCallAsync( + { ...callData, data: this.getABIEncodedTransactionData() }, + defaultBlock, + ); + const abiEncoder = self._lookupAbiEncoder(functionSignature); + return abiEncoder.strictDecodeReturnValue(rawCallResult); + }, + getABIEncodedTransactionData(): string { + return self._strictEncodeArguments(functionSignature, [values, nestedAssetData]); + }, + }; + } + /** + * Function signature for encoding StaticCall assetData. + * @param staticCallTargetAddress Address that will execute the staticcall. + * @param staticCallData Data that will be executed via staticcall on the + * staticCallTargetAddress. + * @param expectedReturnDataHash Keccak-256 hash of the expected staticcall + * return data. + */ + public StaticCall( + staticCallTargetAddress: string, + staticCallData: string, + expectedReturnDataHash: string, + ): ContractTxFunctionObj { + const self = (this as any) as IAssetDataContract; + assert.isString('staticCallTargetAddress', staticCallTargetAddress); + assert.isString('staticCallData', staticCallData); + assert.isString('expectedReturnDataHash', expectedReturnDataHash); + const functionSignature = 'StaticCall(address,bytes,bytes32)'; + + return { + async sendTransactionAsync( + txData?: Partial | undefined, + opts: SendTransactionOpts = { shouldValidate: true }, + ): Promise { + const txDataWithDefaults = await self._applyDefaultsToTxDataAsync( + { ...txData, data: this.getABIEncodedTransactionData() }, + this.estimateGasAsync.bind(this), + ); + if (opts.shouldValidate !== false) { + await this.callAsync(txDataWithDefaults); + } + return self._web3Wrapper.sendTransactionAsync(txDataWithDefaults); + }, + awaitTransactionSuccessAsync( + txData?: Partial, + opts: AwaitTransactionSuccessOpts = { shouldValidate: true }, + ): PromiseWithTransactionHash { + return self._promiseWithTransactionHash(this.sendTransactionAsync(txData, opts), opts); + }, + async estimateGasAsync(txData?: Partial | undefined): Promise { + const txDataWithDefaults = await self._applyDefaultsToTxDataAsync({ + ...txData, + data: this.getABIEncodedTransactionData(), + }); + return self._web3Wrapper.estimateGasAsync(txDataWithDefaults); + }, + async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { + BaseContract._assertCallParams(callData, defaultBlock); + const rawCallResult = await self._performCallAsync( + { ...callData, data: this.getABIEncodedTransactionData() }, + defaultBlock, + ); + const abiEncoder = self._lookupAbiEncoder(functionSignature); + return abiEncoder.strictDecodeReturnValue(rawCallResult); + }, + getABIEncodedTransactionData(): string { + return self._strictEncodeArguments(functionSignature, [ + staticCallTargetAddress.toLowerCase(), + staticCallData, + expectedReturnDataHash, + ]); + }, + }; + } + + constructor( + address: string, + supportedProvider: SupportedProvider, + txDefaults?: Partial, + logDecodeDependencies?: { [contractName: string]: ContractAbi }, + deployedBytecode: string | undefined = IAssetDataContract.deployedBytecode, + ) { + super( + 'IAssetData', + IAssetDataContract.ABI(), + address, + supportedProvider, + txDefaults, + logDecodeDependencies, + deployedBytecode, + ); + classUtils.bindAll(this, ['_abiEncoderByFunctionSignature', 'address', '_web3Wrapper']); + IAssetDataContract.ABI().forEach((item, index) => { + if (item.type === 'function') { + const methodAbi = item as MethodAbi; + this._methodABIIndex[methodAbi.name] = index; + } + }); + } +} + +// tslint:disable:max-file-line-count +// tslint:enable:no-unbound-method no-parameter-reassignment no-consecutive-blank-lines ordered-imports align +// tslint:enable:trailing-comma whitespace no-trailing-whitespace diff --git a/packages/contract-wrappers/src/index.ts b/packages/contract-wrappers/src/index.ts index 7442cff28d..2245f89af3 100644 --- a/packages/contract-wrappers/src/index.ts +++ b/packages/contract-wrappers/src/index.ts @@ -2,6 +2,7 @@ export { ContractAddresses } from '@0x/contract-addresses'; export { ContractWrappers } from './contract_wrappers'; export { DevUtilsContract } from './generated-wrappers/dev_utils'; +export { IAssetDataContract } from './generated-wrappers/i_asset_data'; // used for synchronously encoding and decoding asset data export { ERC20TokenEventArgs, ERC20TokenEvents, diff --git a/packages/instant/package.json b/packages/instant/package.json index 91ed23246f..4bbfc70be1 100644 --- a/packages/instant/package.json +++ b/packages/instant/package.json @@ -45,8 +45,8 @@ "dependencies": { "@0x/assert": "^3.0.0", "@0x/asset-swapper": "^3.0.0", + "@0x/contract-wrappers": "13.0.0", "@0x/json-schemas": "^5.0.0", - "@0x/order-utils": "^9.0.0", "@0x/subproviders": "^6.0.0", "@0x/utils": "^5.0.0", "@0x/web3-wrapper": "^7.0.0", diff --git a/packages/instant/src/index.umd.ts b/packages/instant/src/index.umd.ts index d430f5c056..e5a89451ae 100644 --- a/packages/instant/src/index.umd.ts +++ b/packages/instant/src/index.umd.ts @@ -1,5 +1,4 @@ import { BigNumber, SwapQuoter } from '@0x/asset-swapper'; -import { assetDataUtils } from '@0x/order-utils'; import { AssetProxyId } from '@0x/types'; import { providerUtils } from '@0x/utils'; import { SupportedProvider, ZeroExProvider } from 'ethereum-types'; @@ -19,6 +18,7 @@ import { ZeroExInstantOverlay, ZeroExInstantOverlayProps } from './index'; import { Network, OrderSource } from './types'; import { analytics } from './util/analytics'; import { assert } from './util/assert'; +import { assetDataEncoder } from './util/asset_data_encoder'; import { orderCoercionUtil } from './util/order_coercion'; import { providerFactory } from './util/provider_factory'; import { util } from './util/util'; @@ -158,12 +158,12 @@ export const ERC20_PROXY_ID = AssetProxyId.ERC20; export const assetDataForERC20TokenAddress = (tokenAddress: string): string => { assert.isETHAddressHex('tokenAddress', tokenAddress); - return assetDataUtils.encodeERC20AssetData(tokenAddress); + return assetDataEncoder.ERC20Token(tokenAddress).getABIEncodedTransactionData(); }; export const assetDataForERC721TokenAddress = (tokenAddress: string, tokenId: string | number): string => { assert.isETHAddressHex('tokenAddress', tokenAddress); - return assetDataUtils.encodeERC721AssetData(tokenAddress, new BigNumber(tokenId)); + return assetDataEncoder.ERC721Token(tokenAddress, new BigNumber(tokenId)).getABIEncodedTransactionData(); }; export const hasMetaDataForAssetData = (assetData: string): boolean => { diff --git a/packages/instant/src/util/assert.ts b/packages/instant/src/util/assert.ts index ee21c31f97..f9ba7aa767 100644 --- a/packages/instant/src/util/assert.ts +++ b/packages/instant/src/util/assert.ts @@ -1,11 +1,12 @@ import { assert as sharedAssert } from '@0x/assert'; import { schemas } from '@0x/json-schemas'; -import { assetDataUtils } from '@0x/order-utils'; import { AssetProxyId, ObjectMap, SignedOrder } from '@0x/types'; import * as _ from 'lodash'; import { AffiliateInfo, AssetMetaData } from '../types'; +import { decodeAssetProxyId } from './asset_data_encoder'; + export const assert = { ...sharedAssert, isValidOrderSource(variableName: string, orderSource: string | SignedOrder[]): void { @@ -22,7 +23,7 @@ export const assert = { _.forEach(metaDataMap, (metaData, assetData) => { assert.isHexString(`key ${assetData} of ${variableName}`, assetData); assert.isValidAssetMetaData(`${variableName}.${assetData}`, metaData); - const assetDataProxyId = assetDataUtils.decodeAssetProxyId(assetData); + const assetDataProxyId = decodeAssetProxyId(assetData); assert.assert( metaData.assetProxyId === assetDataProxyId, `Expected meta data for assetData ${assetData} to have asset proxy id of ${assetDataProxyId}, but instead got ${ diff --git a/packages/instant/src/util/asset_data_encoder.ts b/packages/instant/src/util/asset_data_encoder.ts new file mode 100644 index 0000000000..1a4800028b --- /dev/null +++ b/packages/instant/src/util/asset_data_encoder.ts @@ -0,0 +1,19 @@ +import { IAssetDataContract } from '@0x/contract-wrappers'; +import { hexUtils, NULL_ADDRESS } from '@0x/utils'; + +const fakeProvider = { isEIP1193: true } as any; + +// instantiate once per app to be more performant +export const assetDataEncoder = new IAssetDataContract(NULL_ADDRESS, fakeProvider); + +/** + * Returns the first four bytes of a given hex string. + * Does not have any validations, so the hex string MUST + * be a valid asset data, or this function returns garbage + * without throwing errors. + * @param assetData A hex string where the first four bytes are a valid Asset Proxy Id + * + */ +export function decodeAssetProxyId(assetData: string): string { + return hexUtils.slice(assetData, 0, 4); +} diff --git a/packages/order-utils/CHANGELOG.json b/packages/order-utils/CHANGELOG.json index ddc5b9fab9..148625faeb 100644 --- a/packages/order-utils/CHANGELOG.json +++ b/packages/order-utils/CHANGELOG.json @@ -1,4 +1,17 @@ [ + { + "version": "10.0.0", + "changes": [ + { + "note": "Removed `assetDataUtils`", + "pr": 2373 + }, + { + "note": "Exported function `decodeAssetDataOrThrow`", + "pr": 2373 + } + ] + }, { "version": "9.0.0", "changes": [ diff --git a/packages/order-utils/src/asset_data_utils.ts b/packages/order-utils/src/asset_data_utils.ts deleted file mode 100644 index 712d37dfb4..0000000000 --- a/packages/order-utils/src/asset_data_utils.ts +++ /dev/null @@ -1,469 +0,0 @@ -import { - AssetProxyId, - ERC1155AssetData, - ERC1155AssetDataNoProxyId, - ERC20AssetData, - ERC721AssetData, - MultiAssetData, - MultiAssetDataWithRecursiveDecoding, - SingleAssetData, - StaticCallAssetData, -} from '@0x/types'; -import { AbiEncoder, BigNumber } from '@0x/utils'; -import * as _ from 'lodash'; - -import { constants } from './constants'; - -const encodingRules: AbiEncoder.EncodingRules = { shouldOptimize: true }; -const decodingRules: AbiEncoder.DecodingRules = { shouldConvertStructsToObjects: true }; - -export const assetDataUtils = { - /** - * Encodes an ERC20 token address into a hex encoded assetData string, usable in the makerAssetData or - * takerAssetData fields in a 0x order. - * @param tokenAddress The ERC20 token address to encode - * @return The hex encoded assetData string - */ - encodeERC20AssetData(tokenAddress: string): string { - const abiEncoder = new AbiEncoder.Method(constants.ERC20_METHOD_ABI); - const args = [tokenAddress]; - const assetData = abiEncoder.encode(args, encodingRules); - return assetData; - }, - /** - * Decodes an ERC20 assetData hex string into its corresponding ERC20 tokenAddress & assetProxyId - * @param assetData Hex encoded assetData string to decode - * @return An object containing the decoded tokenAddress & assetProxyId - */ - decodeERC20AssetData(assetData: string): ERC20AssetData { - assetDataUtils.assertIsERC20AssetData(assetData); - const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData); - const abiEncoder = new AbiEncoder.Method(constants.ERC20_METHOD_ABI); - const decodedAssetData = abiEncoder.decode(assetData, decodingRules); - return { - assetProxyId, - // TODO(abandeali1): fix return types for `AbiEncoder.Method.decode` so that we can remove type assertion - tokenAddress: (decodedAssetData as any).tokenContract, - }; - }, - /** - * Encodes an ERC721 token address into a hex encoded assetData string, usable in the makerAssetData or - * takerAssetData fields in a 0x order. - * @param tokenAddress The ERC721 token address to encode - * @param tokenId The ERC721 tokenId to encode - * @return The hex encoded assetData string - */ - encodeERC721AssetData(tokenAddress: string, tokenId: BigNumber): string { - const abiEncoder = new AbiEncoder.Method(constants.ERC721_METHOD_ABI); - const args = [tokenAddress, tokenId]; - const assetData = abiEncoder.encode(args, encodingRules); - return assetData; - }, - /** - * Decodes an ERC721 assetData hex string into its corresponding ERC721 tokenAddress, tokenId & assetProxyId - * @param assetData Hex encoded assetData string to decode - * @return An object containing the decoded tokenAddress, tokenId & assetProxyId - */ - decodeERC721AssetData(assetData: string): ERC721AssetData { - assetDataUtils.assertIsERC721AssetData(assetData); - const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData); - const abiEncoder = new AbiEncoder.Method(constants.ERC721_METHOD_ABI); - const decodedAssetData = abiEncoder.decode(assetData, decodingRules); - return { - assetProxyId, - // TODO(abandeali1): fix return types for `AbiEncoder.Method.decode` so that we can remove type assertion - tokenAddress: (decodedAssetData as any).tokenContract, - tokenId: (decodedAssetData as any).tokenId, - }; - }, - /** - * Encodes a set of ERC1155 assets into an assetData string, usable in the makerAssetData or - * takerAssetData fields of a 0x order. - * @param tokenAddress The token address of the ERC1155 contract - * @param tokenIds The Id's of the ERC1155 tokens to transfer - * @param tokenValues The values of each respective token Id to transfer - * @param callbackData The data forwarded to a receiver, if receiver is a contract. - * @return The hex encoded assetData string - */ - encodeERC1155AssetData( - tokenAddress: string, - tokenIds: BigNumber[], - tokenValues: BigNumber[], - callbackData: string, - ): string { - const abiEncoder = AbiEncoder.createMethod('ERC1155Assets', constants.ERC1155_METHOD_ABI.inputs); - const args = [tokenAddress, tokenIds, tokenValues, callbackData]; - const assetData = abiEncoder.encode(args, encodingRules); - return assetData; - }, - /** - * Decodes an ERC1155 assetData hex string into its corresponding ERC1155 components. - * @param assetData Hex encoded assetData string to decode - * @return An object containing the decoded tokenAddress, tokenIds, tokenValues, callbackData & assetProxyId - */ - decodeERC1155AssetData(assetData: string): ERC1155AssetData { - const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData); - if (assetProxyId !== AssetProxyId.ERC1155) { - throw new Error(`Invalid assetProxyId. Expected '${AssetProxyId.ERC1155}', got '${assetProxyId}'`); - } - const abiEncoder = AbiEncoder.createMethod('ERC1155Assets', constants.ERC1155_METHOD_ABI.inputs); - // tslint:disable-next-line:no-unnecessary-type-assertion - const decodedAssetData = abiEncoder.decode(assetData, decodingRules) as ERC1155AssetDataNoProxyId; - return { - assetProxyId, - tokenAddress: decodedAssetData.tokenAddress, - tokenIds: decodedAssetData.tokenIds, - tokenValues: decodedAssetData.tokenValues, - callbackData: decodedAssetData.callbackData, - }; - }, - /** - * Encodes assetData for multiple AssetProxies into a single hex encoded assetData string, usable in the makerAssetData or - * takerAssetData fields in a 0x order. - * @param amounts Amounts of each asset that correspond to a single unit within an order. - * @param nestedAssetData assetData strings that correspond to a valid assetProxyId. - * @return The hex encoded assetData string - */ - encodeMultiAssetData(amounts: BigNumber[], nestedAssetData: string[]): string { - if (amounts.length !== nestedAssetData.length) { - throw new Error( - `Invalid MultiAsset arguments. Expected length of 'amounts' (${ - amounts.length - }) to equal length of 'nestedAssetData' (${nestedAssetData.length})`, - ); - } - _.forEach(nestedAssetData, assetDataElement => assetDataUtils.validateAssetDataOrThrow(assetDataElement)); - const abiEncoder = new AbiEncoder.Method(constants.MULTI_ASSET_METHOD_ABI); - const args = [amounts, nestedAssetData]; - const assetData = abiEncoder.encode(args, encodingRules); - return assetData; - }, - /** - * Decodes a MultiAsset assetData hex string into its corresponding amounts and nestedAssetData - * @param assetData Hex encoded assetData string to decode - * @return An object containing the decoded amounts and nestedAssetData - */ - decodeMultiAssetData(assetData: string): MultiAssetData { - assetDataUtils.assertIsMultiAssetData(assetData); - const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData); - const abiEncoder = new AbiEncoder.Method(constants.MULTI_ASSET_METHOD_ABI); - const decodedAssetData = abiEncoder.decode(assetData, decodingRules); - // TODO(abandeali1): fix return types for `AbiEncoder.Method.decode` so that we can remove type assertion - const amounts = (decodedAssetData as any).amounts; - const nestedAssetData = (decodedAssetData as any).nestedAssetData; - if (amounts.length !== nestedAssetData.length) { - throw new Error( - `Invalid MultiAsset assetData. Expected length of 'amounts' (${ - amounts.length - }) to equal length of 'nestedAssetData' (${nestedAssetData.length})`, - ); - } - return { - assetProxyId, - amounts, - nestedAssetData, - }; - }, - /** - * Decodes a MultiAsset assetData hex string into its corresponding amounts and decoded nestedAssetData elements (all nested elements are flattened) - * @param assetData Hex encoded assetData string to decode - * @return An object containing the decoded amounts and nestedAssetData - */ - decodeMultiAssetDataRecursively(assetData: string): MultiAssetDataWithRecursiveDecoding { - const decodedAssetData = assetDataUtils.decodeMultiAssetData(assetData); - const amounts: any[] = []; - const decodedNestedAssetData = _.map( - decodedAssetData.nestedAssetData as string[], - (nestedAssetDataElement, index) => { - const decodedNestedAssetDataElement = assetDataUtils.decodeAssetDataOrThrow(nestedAssetDataElement); - if (decodedNestedAssetDataElement.assetProxyId === AssetProxyId.MultiAsset) { - const recursivelyDecodedAssetData = assetDataUtils.decodeMultiAssetDataRecursively( - nestedAssetDataElement, - ); - amounts.push( - _.map(recursivelyDecodedAssetData.amounts, amountElement => - amountElement.times(decodedAssetData.amounts[index]), - ), - ); - return recursivelyDecodedAssetData.nestedAssetData; - } else { - amounts.push(decodedAssetData.amounts[index]); - return decodedNestedAssetDataElement as SingleAssetData; - } - }, - ); - const flattenedAmounts = _.flattenDeep(amounts); - const flattenedDecodedNestedAssetData = _.flattenDeep(decodedNestedAssetData); - return { - assetProxyId: decodedAssetData.assetProxyId, - amounts: flattenedAmounts, - // tslint:disable-next-line:no-unnecessary-type-assertion - nestedAssetData: flattenedDecodedNestedAssetData as SingleAssetData[], - }; - }, - /** - * Encodes StaticCallProxy data into an assetData hex string - * @param callTarget Address of contract to call from StaticCallProxy - * @param staticCallData The function data that will be called on the callTarget contract - * @param callResultHash The keccak256 hash of the ABI encoded expected output of the static call - * @return The hex encoded assetData string - */ - encodeStaticCallAssetData(callTarget: string, staticCallData: string, callResultHash: string): string { - const abiEncoder = AbiEncoder.createMethod('StaticCall', constants.STATIC_CALL_METHOD_ABI.inputs); - const args = [callTarget, staticCallData, callResultHash]; - const assetData = abiEncoder.encode(args, encodingRules); - return assetData; - }, - /** - * Decoded StaticCall assetData into its corresponding callTarget, staticCallData, and expected callResultHash - * @param assetData Hex encoded assetData string to decode - * @return An object containing the decoded callTarget, staticCallData, and expected callResultHash - */ - decodeStaticCallAssetData(assetData: string): StaticCallAssetData { - const abiEncoder = AbiEncoder.createMethod('StaticCall', constants.STATIC_CALL_METHOD_ABI.inputs); - const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData); - const decodedAssetData = abiEncoder.decode(assetData, decodingRules) as any; - return { - assetProxyId, - callTarget: decodedAssetData.callTarget, - callResultHash: decodedAssetData.callResultHash, - staticCallData: decodedAssetData.staticCallData, - }; - }, - /** - * Decode and return the assetProxyId from the assetData - * @param assetData Hex encoded assetData string to decode - * @return The assetProxyId - */ - decodeAssetProxyId(assetData: string): AssetProxyId { - if (assetData.length < constants.SELECTOR_CHAR_LENGTH_WITH_PREFIX) { - throw new Error( - `Could not decode assetData. Expected length of encoded data to be at least 10. Got ${ - assetData.length - }`, - ); - } - const assetProxyId = assetData.slice(0, constants.SELECTOR_CHAR_LENGTH_WITH_PREFIX); - if ( - assetProxyId !== AssetProxyId.ERC20 && - assetProxyId !== AssetProxyId.ERC721 && - assetProxyId !== AssetProxyId.ERC1155 && - assetProxyId !== AssetProxyId.StaticCall && - assetProxyId !== AssetProxyId.MultiAsset - ) { - throw new Error(`Invalid assetProxyId: ${assetProxyId}`); - } - return assetProxyId; - }, - /** - * Checks if the decoded asset data is valid ERC20 data - * @param decodedAssetData The decoded asset data to check - */ - isERC20AssetData(decodedAssetData: SingleAssetData | MultiAssetData): decodedAssetData is ERC20AssetData { - return decodedAssetData.assetProxyId === AssetProxyId.ERC20; - }, - /** - * Checks if the decoded asset data is valid ERC721 data - * @param decodedAssetData The decoded asset data to check - */ - isERC721AssetData(decodedAssetData: SingleAssetData | MultiAssetData): decodedAssetData is ERC721AssetData { - return decodedAssetData.assetProxyId === AssetProxyId.ERC721; - }, - /** - * Checks if the decoded asset data is valid ERC1155 data - * @param decodedAssetData The decoded asset data to check - */ - isERC1155AssetData(decodedAssetData: SingleAssetData | MultiAssetData): decodedAssetData is ERC1155AssetData { - return decodedAssetData.assetProxyId === AssetProxyId.ERC1155; - }, - /** - * Checks if the decoded asset data is valid MultiAsset data - * @param decodedAssetData The decoded asset data to check - */ - isMultiAssetData(decodedAssetData: SingleAssetData | MultiAssetData): decodedAssetData is MultiAssetData { - return decodedAssetData.assetProxyId === AssetProxyId.MultiAsset; - }, - /** - * Checks if the decoded asset data is valid StaticCall data - * @param decodedAssetData The decoded asset data to check - */ - isStaticCallAssetData(decodedAssetData: SingleAssetData | MultiAssetData): decodedAssetData is StaticCallAssetData { - return decodedAssetData.assetProxyId === AssetProxyId.StaticCall; - }, - /** - * Throws if the length or assetProxyId are invalid for the ERC20Proxy. - * @param assetData Hex encoded assetData string - */ - assertIsERC20AssetData(assetData: string): void { - if (assetData.length < constants.ERC20_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX) { - throw new Error( - `Could not decode ERC20 Proxy Data. Expected length of encoded data to be at least ${ - constants.ERC20_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX - }. Got ${assetData.length}`, - ); - } - assetDataUtils.assertWordAlignedAssetData(assetData); - const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData); - if (assetProxyId !== AssetProxyId.ERC20) { - throw new Error( - `Could not decode ERC20 assetData. Expected assetProxyId to be ERC20 (${ - AssetProxyId.ERC20 - }), but got ${assetProxyId}`, - ); - } - }, - /** - * Throws if the length or assetProxyId are invalid for the ERC721Proxy. - * @param assetData Hex encoded assetData string - */ - assertIsERC721AssetData(assetData: string): void { - if (assetData.length < constants.ERC721_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX) { - throw new Error( - `Could not decode ERC721 assetData. Expected length of encoded data to be at least ${ - constants.ERC721_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX - }. Got ${assetData.length}`, - ); - } - assetDataUtils.assertWordAlignedAssetData(assetData); - const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData); - if (assetProxyId !== AssetProxyId.ERC721) { - throw new Error( - `Could not decode ERC721 assetData. Expected assetProxyId to be ERC721 (${ - AssetProxyId.ERC721 - }), but got ${assetProxyId}`, - ); - } - }, - /** - * Throws if the assetData is not ERC1155. - * @param assetData Hex encoded assetData string - */ - assertIsERC1155AssetData(assetData: string): void { - if (assetData.length < constants.ERC1155_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX) { - throw new Error( - `Could not decode ERC1155 Proxy Data. Expected length of encoded data to be at least ${ - constants.ERC1155_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX - }. Got ${assetData.length}`, - ); - } - assetDataUtils.assertWordAlignedAssetData(assetData); - const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData); - if (assetProxyId !== AssetProxyId.ERC1155) { - throw new Error( - `Could not decode ERC1155 assetData. Expected assetProxyId to be ERC1155 (${ - AssetProxyId.ERC1155 - }), but got ${assetProxyId}`, - ); - } - }, - /** - * Throws if the length or assetProxyId are invalid for the MultiAssetProxy. - * @param assetData Hex encoded assetData string - */ - assertIsMultiAssetData(assetData: string): void { - if (assetData.length < constants.MULTI_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX) { - throw new Error( - `Could not decode MultiAsset assetData. Expected length of encoded data to be at least ${ - constants.MULTI_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX - }. Got ${assetData.length}`, - ); - } - assetDataUtils.assertWordAlignedAssetData(assetData); - const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData); - if (assetProxyId !== AssetProxyId.MultiAsset) { - throw new Error( - `Could not decode MultiAsset assetData. Expected assetProxyId to be MultiAsset (${ - AssetProxyId.MultiAsset - }), but got ${assetProxyId}`, - ); - } - }, - /** - * Throws if the assetData is not StaticCallData. - * @param assetData Hex encoded assetData string - */ - assertIsStaticCallAssetData(assetData: string): void { - if (assetData.length < constants.STATIC_CALL_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX) { - throw new Error( - `Could not decode StaticCall Proxy Data. Expected length of encoded data to be at least ${ - constants.STATIC_CALL_ASSET_DATA_MIN_CHAR_LENGTH_WITH_PREFIX - }. Got ${assetData.length}`, - ); - } - assetDataUtils.assertWordAlignedAssetData(assetData); - const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData); - if (assetProxyId !== AssetProxyId.StaticCall) { - throw new Error( - `Could not decode StaticCall assetData. Expected assetProxyId to be StaticCall (${ - AssetProxyId.StaticCall - }), but got ${assetProxyId}`, - ); - } - }, - /** - * Throws if the assetData is not padded to 32 bytes. - * @param assetData Hex encoded assetData string - */ - assertWordAlignedAssetData(assetData: string): void { - const charsIn32Bytes = 64; - if ((assetData.length - constants.SELECTOR_CHAR_LENGTH_WITH_PREFIX) % charsIn32Bytes !== 0) { - throw new Error( - `assetData must be word aligned. ${(assetData.length - 2) / 2} is not a valid byte length.`, - ); - } - }, - /** - * Throws if the length or assetProxyId are invalid for the corresponding AssetProxy. - * @param assetData Hex encoded assetData string - */ - validateAssetDataOrThrow(assetData: string): void { - const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData); - switch (assetProxyId) { - case AssetProxyId.ERC20: - assetDataUtils.assertIsERC20AssetData(assetData); - break; - case AssetProxyId.ERC721: - assetDataUtils.assertIsERC721AssetData(assetData); - break; - case AssetProxyId.ERC1155: - assetDataUtils.assertIsERC1155AssetData(assetData); - break; - case AssetProxyId.MultiAsset: - assetDataUtils.assertIsMultiAssetData(assetData); - break; - case AssetProxyId.StaticCall: - assetDataUtils.assertIsStaticCallAssetData(assetData); - break; - default: - throw new Error(`Unrecognized asset proxy id: ${assetProxyId}`); - } - }, - /** - * Decode any assetData into its corresponding assetData object - * @param assetData Hex encoded assetData string to decode - * @return Either a ERC20, ERC721, ERC1155, or MultiAsset assetData object - */ - decodeAssetDataOrThrow(assetData: string): SingleAssetData | MultiAssetData { - const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData); - switch (assetProxyId) { - case AssetProxyId.ERC20: - const erc20AssetData = assetDataUtils.decodeERC20AssetData(assetData); - return erc20AssetData; - case AssetProxyId.ERC721: - const erc721AssetData = assetDataUtils.decodeERC721AssetData(assetData); - return erc721AssetData; - case AssetProxyId.ERC1155: - const erc1155AssetData = assetDataUtils.decodeERC1155AssetData(assetData); - return erc1155AssetData; - case AssetProxyId.MultiAsset: - const multiAssetData = assetDataUtils.decodeMultiAssetData(assetData); - return multiAssetData; - case AssetProxyId.StaticCall: - const staticCallData = assetDataUtils.decodeStaticCallAssetData(assetData); - return staticCallData; - default: - throw new Error(`Unrecognized asset proxy id: ${assetProxyId}`); - } - }, -}; -// tslint:disable:max-file-line-count diff --git a/packages/order-utils/src/decode_asset_data.ts b/packages/order-utils/src/decode_asset_data.ts new file mode 100644 index 0000000000..74517b273a --- /dev/null +++ b/packages/order-utils/src/decode_asset_data.ts @@ -0,0 +1,80 @@ +import { IAssetDataContract } from '@0x/contract-wrappers'; +import { AssetData, AssetProxyId } from '@0x/types'; +import { BigNumber, hexUtils, NULL_ADDRESS } from '@0x/utils'; + +const fakeProvider = { isEIP1193: true } as any; +const assetDataDecoder = new IAssetDataContract(NULL_ADDRESS, fakeProvider); + +/** + * Decode any assetData into its corresponding assetData object + * @param assetData Hex encoded assetData string to decode + * @return Either a ERC20, ERC20Bridge, ERC721, ERC1155, StaticCall, or MultiAsset assetData object + */ +export function decodeAssetDataOrThrow(assetData: string): AssetData { + const assetProxyId = hexUtils.slice(assetData, 0, 4); // tslint:disable-line:custom-no-magic-numbers + switch (assetProxyId) { + case AssetProxyId.ERC20: { + const tokenAddress = assetDataDecoder.getABIDecodedTransactionData('ERC20Token', assetData); + return { + assetProxyId, + tokenAddress, + }; + } + case AssetProxyId.ERC20Bridge: { + const [tokenAddress, bridgeAddress, bridgeData] = assetDataDecoder.getABIDecodedTransactionData< + [string, string, string] + >('ERC20Bridge', assetData); + return { + assetProxyId, + tokenAddress, + bridgeAddress, + bridgeData, + }; + } + case AssetProxyId.ERC721: { + const [tokenAddress, tokenId] = assetDataDecoder.getABIDecodedTransactionData<[string, BigNumber]>( + 'ERC721Token', + assetData, + ); + return { + assetProxyId, + tokenAddress, + tokenId, + }; + } + case AssetProxyId.ERC1155: { + const [tokenAddress, tokenIds, tokenValues] = assetDataDecoder.getABIDecodedTransactionData< + [string, BigNumber[], BigNumber[]] + >('ERC1155Assets', assetData); + return { + assetProxyId, + tokenAddress, + tokenIds, + tokenValues, + }; + } + case AssetProxyId.MultiAsset: { + const [amounts, nestedAssetData] = assetDataDecoder.getABIDecodedTransactionData<[BigNumber[], string[]]>( + 'MultiAsset', + assetData, + ); + return { + assetProxyId, + amounts, + nestedAssetData, + }; + } + case AssetProxyId.StaticCall: + const [callTarget, staticCallData, callResultHash] = assetDataDecoder.getABIDecodedTransactionData< + [string, string, string] + >('StaticCall', assetData); + return { + assetProxyId, + callTarget, + staticCallData, + callResultHash, + }; + default: + throw new Error(`Unhandled asset proxy ID: ${assetProxyId}`); + } +} diff --git a/packages/order-utils/src/index.ts b/packages/order-utils/src/index.ts index 0458bd603f..eada7f5faf 100644 --- a/packages/order-utils/src/index.ts +++ b/packages/order-utils/src/index.ts @@ -1,11 +1,11 @@ export { signatureUtils } from './signature_utils'; export { generatePseudoRandomSalt } from './salt'; -export { assetDataUtils } from './asset_data_utils'; export { marketUtils } from './market_utils'; export { rateUtils } from './rate_utils'; export { sortingUtils } from './sorting_utils'; export { orderCalculationUtils } from './order_calculation_utils'; export { orderHashUtils } from './order_hash_utils'; +export { decodeAssetDataOrThrow } from './decode_asset_data'; export { eip712Utils } from './eip712_utils'; @@ -29,14 +29,15 @@ export { SignedOrder, Order, ECSignature, + AssetData, SingleAssetData, ERC20AssetData, + ERC20BridgeAssetData, ERC721AssetData, ERC1155AssetData, MultiAssetData, StaticCallAssetData, MultiAssetDataWithRecursiveDecoding, - AssetProxyId, SignatureType, EIP712Parameter, EIP712TypedData, diff --git a/packages/order-utils/test/asset_data_utils_test.ts b/packages/order-utils/test/asset_data_utils_test.ts deleted file mode 100644 index ab168e9fa9..0000000000 --- a/packages/order-utils/test/asset_data_utils_test.ts +++ /dev/null @@ -1,178 +0,0 @@ -import * as chai from 'chai'; - -import { AssetProxyId, ERC1155AssetData, ERC20AssetData, ERC721AssetData } from '@0x/types'; -import { BigNumber } from '@0x/utils'; - -import { assetDataUtils } from '../src/asset_data_utils'; - -import { chaiSetup } from './utils/chai_setup'; - -chaiSetup.configure(); -const expect = chai.expect; - -const KNOWN_ERC20_ENCODING = { - address: '0x1dc4c1cefef38a777b15aa20260a54e584b16c48', - assetData: '0xf47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48', -}; -const KNOWN_ERC721_ENCODING = { - address: '0x1dc4c1cefef38a777b15aa20260a54e584b16c48', - tokenId: new BigNumber(1), - assetData: - '0x025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000001', -}; -const KNOWN_ERC1155_ENCODING = { - tokenAddress: '0x1dc4c1cefef38a777b15aa20260a54e584b16c48', - tokenIds: [new BigNumber(100), new BigNumber(1001), new BigNumber(10001)], - tokenValues: [new BigNumber(200), new BigNumber(2001), new BigNumber(20001)], - callbackData: - '0x025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000001', - assetData: - '0xa7cb5fb70000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000003e90000000000000000000000000000000000000000000000000000000000002711000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000007d10000000000000000000000000000000000000000000000000000000000004e210000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000', -}; -const KNOWN_MULTI_ASSET_ENCODING = { - amounts: [new BigNumber(70), new BigNumber(1), new BigNumber(18)], - nestedAssetData: [ - KNOWN_ERC20_ENCODING.assetData, - KNOWN_ERC721_ENCODING.assetData, - KNOWN_ERC1155_ENCODING.assetData, - ], - assetData: - '0x94cfcdd7000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000024f47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000204a7cb5fb70000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000003e90000000000000000000000000000000000000000000000000000000000002711000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000007d10000000000000000000000000000000000000000000000000000000000004e210000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c4800000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', -}; - -describe('assetDataUtils', () => { - it('should encode ERC20', () => { - const assetData = assetDataUtils.encodeERC20AssetData(KNOWN_ERC20_ENCODING.address); - expect(assetData).to.equal(KNOWN_ERC20_ENCODING.assetData); - }); - it('should decode ERC20', () => { - const decodedAssetData = assetDataUtils.decodeERC20AssetData(KNOWN_ERC20_ENCODING.assetData); - expect(decodedAssetData.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address); - expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.ERC20); - }); - it('should encode ERC721', () => { - const assetData = assetDataUtils.encodeERC721AssetData( - KNOWN_ERC721_ENCODING.address, - KNOWN_ERC721_ENCODING.tokenId, - ); - expect(assetData).to.equal(KNOWN_ERC721_ENCODING.assetData); - }); - it('should decode ERC721', () => { - const decodedAssetData = assetDataUtils.decodeERC721AssetData(KNOWN_ERC721_ENCODING.assetData); - expect(decodedAssetData.tokenAddress).to.equal(KNOWN_ERC721_ENCODING.address); - expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.ERC721); - expect(decodedAssetData.tokenId).to.be.bignumber.equal(KNOWN_ERC721_ENCODING.tokenId); - }); - it('should encode ERC1155', () => { - const assetData = assetDataUtils.encodeERC1155AssetData( - KNOWN_ERC1155_ENCODING.tokenAddress, - KNOWN_ERC1155_ENCODING.tokenIds, - KNOWN_ERC1155_ENCODING.tokenValues, - KNOWN_ERC1155_ENCODING.callbackData, - ); - expect(assetData).to.equal(KNOWN_ERC1155_ENCODING.assetData); - }); - it('should decode ERC1155', () => { - const decodedAssetData = assetDataUtils.decodeERC1155AssetData(KNOWN_ERC1155_ENCODING.assetData); - expect(decodedAssetData.assetProxyId).to.be.equal(AssetProxyId.ERC1155); - expect(decodedAssetData.tokenAddress).to.be.equal(KNOWN_ERC1155_ENCODING.tokenAddress); - expect(decodedAssetData.tokenValues).to.be.deep.equal(KNOWN_ERC1155_ENCODING.tokenValues); - expect(decodedAssetData.tokenIds).to.be.deep.equal(KNOWN_ERC1155_ENCODING.tokenIds); - expect(decodedAssetData.callbackData).to.be.equal(KNOWN_ERC1155_ENCODING.callbackData); - }); - it('should encode ERC20, ERC721 and ERC1155 multiAssetData', () => { - const assetData = assetDataUtils.encodeMultiAssetData( - KNOWN_MULTI_ASSET_ENCODING.amounts, - KNOWN_MULTI_ASSET_ENCODING.nestedAssetData, - ); - expect(assetData).to.equal(KNOWN_MULTI_ASSET_ENCODING.assetData); - }); - it('should decode ERC20, ERC721 and ERC1155 multiAssetData', () => { - const decodedAssetData = assetDataUtils.decodeMultiAssetData(KNOWN_MULTI_ASSET_ENCODING.assetData); - expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.MultiAsset); - expect(decodedAssetData.amounts).to.deep.equal(KNOWN_MULTI_ASSET_ENCODING.amounts); - expect(decodedAssetData.nestedAssetData).to.deep.equal(KNOWN_MULTI_ASSET_ENCODING.nestedAssetData); - }); - it('should recursively decode ERC20 and ERC721 multiAssetData', () => { - const decodedAssetData = assetDataUtils.decodeMultiAssetDataRecursively(KNOWN_MULTI_ASSET_ENCODING.assetData); - expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.MultiAsset); - expect(decodedAssetData.amounts).to.deep.equal(KNOWN_MULTI_ASSET_ENCODING.amounts); - expect(decodedAssetData.nestedAssetData.length).to.equal(3); - // tslint:disable-next-line:no-unnecessary-type-assertion - const decodedErc20AssetData = decodedAssetData.nestedAssetData[0] as ERC20AssetData; - expect(decodedErc20AssetData.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address); - expect(decodedErc20AssetData.assetProxyId).to.equal(AssetProxyId.ERC20); - // tslint:disable-next-line:no-unnecessary-type-assertion - const decodedErc721AssetData = decodedAssetData.nestedAssetData[1] as ERC721AssetData; - expect(decodedErc721AssetData.tokenAddress).to.equal(KNOWN_ERC721_ENCODING.address); - expect(decodedErc721AssetData.assetProxyId).to.equal(AssetProxyId.ERC721); - expect(decodedErc721AssetData.tokenId).to.be.bignumber.equal(KNOWN_ERC721_ENCODING.tokenId); - // tslint:disable-next-line:no-unnecessary-type-assertion - const decodedErc1155AssetData = decodedAssetData.nestedAssetData[2] as ERC1155AssetData; - expect(decodedErc1155AssetData.tokenAddress).to.be.equal(KNOWN_ERC1155_ENCODING.tokenAddress); - expect(decodedErc1155AssetData.tokenValues).to.be.deep.equal(KNOWN_ERC1155_ENCODING.tokenValues); - expect(decodedErc1155AssetData.tokenIds).to.be.deep.equal(KNOWN_ERC1155_ENCODING.tokenIds); - expect(decodedErc1155AssetData.callbackData).to.be.equal(KNOWN_ERC1155_ENCODING.callbackData); - }); - it('should recursively decode nested assetData within multiAssetData', () => { - // setup test parameters - const erc20Amount = new BigNumber(1); - const erc721Amount = new BigNumber(1); - const erc1155Amount = new BigNumber(15); - const nestedAssetsAmount = new BigNumber(2); - const amounts = [erc20Amount, erc721Amount, erc1155Amount, nestedAssetsAmount]; - const nestedAssetData = [ - KNOWN_ERC20_ENCODING.assetData, - KNOWN_ERC721_ENCODING.assetData, - KNOWN_ERC1155_ENCODING.assetData, - KNOWN_MULTI_ASSET_ENCODING.assetData, - ]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); - // execute test - const decodedAssetData = assetDataUtils.decodeMultiAssetDataRecursively(assetData); - // validate asset data - expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.MultiAsset); - const expectedAmounts = [ - erc20Amount, - erc721Amount, - erc1155Amount, - KNOWN_MULTI_ASSET_ENCODING.amounts[0].times(nestedAssetsAmount), - KNOWN_MULTI_ASSET_ENCODING.amounts[1].times(nestedAssetsAmount), - KNOWN_MULTI_ASSET_ENCODING.amounts[2].times(nestedAssetsAmount), - ]; - expect(decodedAssetData.amounts).to.deep.equal(expectedAmounts); - const expectedNestedAssetDataLength = 6; - expect(decodedAssetData.nestedAssetData.length).to.be.equal(expectedNestedAssetDataLength); - // validate nested asset data (outer) - let nestedAssetDataIndex = 0; - // tslint:disable-next-line:no-unnecessary-type-assertion - const decodedErc20AssetData1 = decodedAssetData.nestedAssetData[nestedAssetDataIndex++] as ERC20AssetData; - expect(decodedErc20AssetData1.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address); - expect(decodedErc20AssetData1.assetProxyId).to.equal(AssetProxyId.ERC20); - // tslint:disable-next-line:no-unnecessary-type-assertion - const decodedErc721AssetData1 = decodedAssetData.nestedAssetData[nestedAssetDataIndex++] as ERC721AssetData; - expect(decodedErc721AssetData1.tokenAddress).to.equal(KNOWN_ERC721_ENCODING.address); - expect(decodedErc721AssetData1.assetProxyId).to.equal(AssetProxyId.ERC721); - // tslint:disable-next-line:no-unnecessary-type-assertion - const decodedErc1155AssetData1 = decodedAssetData.nestedAssetData[nestedAssetDataIndex++] as ERC1155AssetData; - expect(decodedErc1155AssetData1.tokenAddress).to.be.equal(KNOWN_ERC1155_ENCODING.tokenAddress); - expect(decodedErc1155AssetData1.tokenValues).to.be.deep.equal(KNOWN_ERC1155_ENCODING.tokenValues); - expect(decodedErc1155AssetData1.tokenIds).to.be.deep.equal(KNOWN_ERC1155_ENCODING.tokenIds); - expect(decodedErc1155AssetData1.callbackData).to.be.equal(KNOWN_ERC1155_ENCODING.callbackData); - // validate nested asset data (inner) - // tslint:disable-next-line:no-unnecessary-type-assertion - const decodedErc20AssetData2 = decodedAssetData.nestedAssetData[nestedAssetDataIndex++] as ERC20AssetData; - expect(decodedErc20AssetData2.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address); - expect(decodedErc20AssetData2.assetProxyId).to.equal(AssetProxyId.ERC20); - // tslint:disable-next-line:no-unnecessary-type-assertion - const decodedErc721AssetData2 = decodedAssetData.nestedAssetData[nestedAssetDataIndex++] as ERC721AssetData; - expect(decodedErc721AssetData2.tokenAddress).to.equal(KNOWN_ERC721_ENCODING.address); - expect(decodedErc721AssetData2.assetProxyId).to.equal(AssetProxyId.ERC721); - // tslint:disable-next-line:no-unnecessary-type-assertion - const decodedErc1155AssetData2 = decodedAssetData.nestedAssetData[nestedAssetDataIndex++] as ERC1155AssetData; - expect(decodedErc1155AssetData2.tokenAddress).to.be.equal(KNOWN_ERC1155_ENCODING.tokenAddress); - expect(decodedErc1155AssetData2.tokenValues).to.be.deep.equal(KNOWN_ERC1155_ENCODING.tokenValues); - expect(decodedErc1155AssetData2.tokenIds).to.be.deep.equal(KNOWN_ERC1155_ENCODING.tokenIds); - expect(decodedErc1155AssetData2.callbackData).to.be.equal(KNOWN_ERC1155_ENCODING.callbackData); - }); -}); diff --git a/packages/types/CHANGELOG.json b/packages/types/CHANGELOG.json index ac6f3e8d94..435b68cd53 100644 --- a/packages/types/CHANGELOG.json +++ b/packages/types/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "3.1.0", + "changes": [ + { + "note": "Add `ERC20BridgeAssetData`", + "pr": 2373 + } + ] + }, { "version": "3.0.0", "changes": [ diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 3af01e21fb..82dbc94c78 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -173,6 +173,13 @@ export interface ERC20AssetData { tokenAddress: string; } +export interface ERC20BridgeAssetData { + assetProxyId: string; + tokenAddress: string; + bridgeAddress: string; + bridgeData: string; +} + export interface ERC721AssetData { assetProxyId: string; tokenAddress: string; @@ -201,7 +208,12 @@ export interface ERC1155AssetDataNoProxyId { callbackData: string; } -export type SingleAssetData = ERC20AssetData | ERC721AssetData | ERC1155AssetData | StaticCallAssetData; +export type SingleAssetData = + | ERC20AssetData + | ERC20BridgeAssetData + | ERC721AssetData + | ERC1155AssetData + | StaticCallAssetData; export interface MultiAssetData { assetProxyId: string; diff --git a/packages/utils/CHANGELOG.json b/packages/utils/CHANGELOG.json index ddb104d946..3b2e502c28 100644 --- a/packages/utils/CHANGELOG.json +++ b/packages/utils/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "5.1.0", + "changes": [ + { + "note": "Added hex_utils", + "pr": 2373 + } + ] + }, { "version": "5.0.0", "changes": [ diff --git a/contracts/test-utils/src/hex_utils.ts b/packages/utils/src/hex_utils.ts similarity index 56% rename from contracts/test-utils/src/hex_utils.ts rename to packages/utils/src/hex_utils.ts index 7a0efae0c6..68dffa03c8 100644 --- a/contracts/test-utils/src/hex_utils.ts +++ b/packages/utils/src/hex_utils.ts @@ -1,46 +1,59 @@ -import { BigNumber } from '@0x/utils'; import * as crypto from 'crypto'; import * as ethUtil from 'ethereumjs-util'; -import { constants } from './constants'; +import { BigNumber } from './index'; import { Numberish } from './types'; -const { WORD_LENGTH } = constants; +// tslint:disable:custom-no-magic-numbers + +const WORD_LENGTH = 32; const WORD_CEIL = new BigNumber(2).pow(WORD_LENGTH * 8); +export const hexUtils = { + concat, + random, + leftPad, + rightPad, + invert, + slice, + hash, + size, + toHex, +}; + /** * Concatenate all arguments as a hex string. */ -export function hexConcat(...args: Array): string { +function concat(...args: Array): string { return ethUtil.bufferToHex(Buffer.concat(args.map(h => ethUtil.toBuffer(h)))); } /** * Generate a random hex string. */ -export function hexRandom(size: number = WORD_LENGTH): string { - return ethUtil.bufferToHex(crypto.randomBytes(size)); +function random(_size: number = WORD_LENGTH): string { + return ethUtil.bufferToHex(crypto.randomBytes(_size)); } /** * Left-pad a hex number to a number of bytes. */ -export function hexLeftPad(n: Numberish, size: number = WORD_LENGTH): string { - return ethUtil.bufferToHex(ethUtil.setLengthLeft(toHex(n), size)); +function leftPad(n: Numberish, _size: number = WORD_LENGTH): string { + return ethUtil.bufferToHex(ethUtil.setLengthLeft(hexUtils.toHex(n), _size)); } /** * Right-pad a hex number to a number of bytes. */ -export function hexRightPad(n: Numberish, size: number = WORD_LENGTH): string { - return ethUtil.bufferToHex(ethUtil.setLengthRight(toHex(n), size)); +function rightPad(n: Numberish, _size: number = WORD_LENGTH): string { + return ethUtil.bufferToHex(ethUtil.setLengthRight(hexUtils.toHex(n), _size)); } /** * Inverts a hex word. */ -export function hexInvert(n: Numberish, size: number = WORD_LENGTH): string { - const buf = ethUtil.setLengthLeft(toHex(n), size); +function invert(n: Numberish, _size: number = WORD_LENGTH): string { + const buf = ethUtil.setLengthLeft(hexUtils.toHex(n), _size); // tslint:disable-next-line: no-bitwise return ethUtil.bufferToHex(Buffer.from(buf.map(b => ~b))); } @@ -48,8 +61,8 @@ export function hexInvert(n: Numberish, size: number = WORD_LENGTH): string { /** * Slices a hex number. */ -export function hexSlice(n: Numberish, start: number, end?: number): string { - const hex = toHex(n).substr(2); +function slice(n: Numberish, start: number, end?: number): string { + const hex = hexUtils.toHex(n).substr(2); const sliceStart = start >= 0 ? start * 2 : Math.max(0, hex.length + start * 2); let sliceEnd = hex.length; if (end !== undefined) { @@ -61,14 +74,14 @@ export function hexSlice(n: Numberish, start: number, end?: number): string { /** * Get the keccak hash of some data. */ -export function hexHash(n: Numberish): string { - return ethUtil.bufferToHex(ethUtil.sha3(ethUtil.toBuffer(toHex(n)))); +function hash(n: Numberish): string { + return ethUtil.bufferToHex(ethUtil.sha3(ethUtil.toBuffer(hexUtils.toHex(n)))); } /** * Get the length, in bytes, of a hex string. */ -export function hexSize(hex: string): number { +function size(hex: string): number { return Math.ceil((hex.length - 2) / 2); } @@ -76,7 +89,7 @@ export function hexSize(hex: string): number { * Convert a string, a number, or a BigNumber into a hex string. * Works with negative numbers, as well. */ -export function toHex(n: Numberish, size: number = WORD_LENGTH): string { +function toHex(n: Numberish, _size: number = WORD_LENGTH): string { if (typeof n === 'string' && /^0x[0-9a-f]+$/i.test(n)) { // Already a hex. return n; @@ -86,9 +99,9 @@ export function toHex(n: Numberish, size: number = WORD_LENGTH): string { // Perform two's-complement. // prettier-ignore _n = new BigNumber( - hexInvert( + invert( toHex(_n.abs()), - size, + _size, ).substr(2), 16, ).plus(1).mod(WORD_CEIL); diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 1a25cb41d6..fedcacbdd7 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -12,6 +12,7 @@ export { NULL_BYTES, NULL_ADDRESS } from './constants'; export { errorUtils } from './error_utils'; export { fetchAsync } from './fetch_async'; export { signTypedDataUtils } from './sign_typed_data_utils'; +export { hexUtils } from './hex_utils'; export import AbiEncoder = require('./abi_encoder'); export * from './types'; export { generatePseudoRandom256BitNumber } from './random'; diff --git a/packages/utils/src/types.ts b/packages/utils/src/types.ts index 1235bfc476..2d7fc749cd 100644 --- a/packages/utils/src/types.ts +++ b/packages/utils/src/types.ts @@ -1,4 +1,5 @@ import { AbiEncoder } from '.'; +import { BigNumber } from './index'; export interface FunctionInfo { functionSignature: string; @@ -17,3 +18,5 @@ export interface DecodedCalldata { functionSignature: string; functionArguments: any; } + +export type Numberish = BigNumber | string | number; diff --git a/yarn.lock b/yarn.lock index 699f0e744f..311249b2dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -643,7 +643,7 @@ npmlog "^4.1.2" write-file-atomic "^2.3.0" -"@0x/abi-gen-wrappers@^5.4.0-beta.2", "@0x/abi-gen-wrappers@^5.4.0-beta.3": +"@0x/abi-gen-wrappers@^5.4.0-beta.3": version "5.4.0-beta.3" resolved "https://registry.yarnpkg.com/@0x/abi-gen-wrappers/-/abi-gen-wrappers-5.4.0-beta.3.tgz#8c2d71ef5695fe2d73359917375cfc99b7ba8112" dependencies: @@ -660,7 +660,6 @@ "@0x/assert@2.2.0-beta.2": version "2.2.0-beta.2" resolved "https://registry.yarnpkg.com/@0x/assert/-/assert-2.2.0-beta.2.tgz#de78c0bb2c9eff263df5bbe743fe73f19ca9c3bd" - integrity sha512-30i5fQ2kqejMkLHMrmqTsZedrJ3DR1KKdO6/CfEtP0wN7eF198yIm1VBHsXGRBWcS+1yCd076qbyj0h2X2Deng== dependencies: "@0x/json-schemas" "^4.1.0-beta.2" "@0x/typescript-typings" "^4.4.0-beta.2" @@ -671,7 +670,6 @@ "@0x/assert@^2.2.0-beta.2", "@0x/assert@^2.2.0-beta.3": version "2.2.0-beta.3" resolved "https://registry.yarnpkg.com/@0x/assert/-/assert-2.2.0-beta.3.tgz#8fb95c265000532cd8dced44d44d29ca544b2bfc" - integrity sha512-ShENc8QJU4ur/5TkRl3l7J3Yt7WaxHAbuoTRm/djcA0iwYyUVlP5yN9Ab9ua+VLizQQTNw1n+kF1mJWg5lQXuA== dependencies: "@0x/json-schemas" "^4.1.0-beta.3" "@0x/typescript-typings" "^4.4.0-beta.2" @@ -679,10 +677,9 @@ lodash "^4.17.11" valid-url "^1.0.9" -"@0x/base-contract@^5.5.0-beta.2", "@0x/base-contract@^5.5.0-beta.3", "@0x/base-contract@^5.5.0-beta.4": +"@0x/base-contract@^5.5.0-beta.3", "@0x/base-contract@^5.5.0-beta.4": version "5.5.0-beta.4" resolved "https://registry.yarnpkg.com/@0x/base-contract/-/base-contract-5.5.0-beta.4.tgz#eb26473e033e1a305a9fa87ab9e26325c9face59" - integrity sha512-6OC3Rg2ESoi1k4wABLt67aMGxqdb6FraeEHdAGb07VuPElpyH9jT8dl2aJFAI8tVcnrUQTXeDYJjuK7rimNReg== dependencies: "@0x/assert" "^2.2.0-beta.3" "@0x/json-schemas" "^4.1.0-beta.3" @@ -696,40 +693,37 @@ js-sha3 "^0.7.0" uuid "^3.3.2" -"@0x/contract-addresses@3.3.0-beta.3": - version "3.3.0-beta.3" - resolved "https://registry.yarnpkg.com/@0x/contract-addresses/-/contract-addresses-3.3.0-beta.3.tgz#0fa8ad47e22aecdb99f9a044ba3c705c4173b61e" +"@0x/contract-addresses@3.3.0-beta.4": + version "3.3.0-beta.4" + resolved "https://registry.yarnpkg.com/@0x/contract-addresses/-/contract-addresses-3.3.0-beta.4.tgz#eec4492702b2e707bcace6ac274f9826761e08a4" dependencies: lodash "^4.17.11" -"@0x/contract-addresses@^3.3.0-beta.3", "@0x/contract-addresses@^3.3.0-beta.4", "@0x/contract-addresses@^3.3.0-beta.5": +"@0x/contract-addresses@^3.3.0-beta.4", "@0x/contract-addresses@^3.3.0-beta.5": version "3.3.0-beta.5" resolved "https://registry.yarnpkg.com/@0x/contract-addresses/-/contract-addresses-3.3.0-beta.5.tgz#9d5f80a258f1d103b127159c237f9bcdad182e80" - integrity sha512-/8de6W1MnVc2zElnCGjK3zgWabBAJZck+zCmNRIMiGtPJIWEW+F3EkAFPfMX6bSZIyrUBlYJIr0xVIWLPU45Aw== dependencies: lodash "^4.17.11" "@0x/contract-artifacts@^2.3.0-beta.3": version "2.3.0-beta.4" resolved "https://registry.yarnpkg.com/@0x/contract-artifacts/-/contract-artifacts-2.3.0-beta.4.tgz#ca056885be387344aaccf5c69fe80aec248df37d" - integrity sha512-NpZk3PVE9c2g5kolCcZej2i1l1XlvCFm9FXAny0tCz+/vNb3RhI0m6ecoiS7b1nFEFZ9q6jjsCCb5OEsxMudnw== -"@0x/contract-wrappers@12.2.0-beta.2": - version "12.2.0-beta.2" - resolved "https://registry.yarnpkg.com/@0x/contract-wrappers/-/contract-wrappers-12.2.0-beta.2.tgz#62b3c13e35282df14734d1f6b1a617ed51901a27" +"@0x/contract-wrappers@12.2.0-beta.3": + version "12.2.0-beta.3" + resolved "https://registry.yarnpkg.com/@0x/contract-wrappers/-/contract-wrappers-12.2.0-beta.3.tgz#e85a7e42170e98244ab57a1089f8831cf10e3f2d" dependencies: - "@0x/abi-gen-wrappers" "^5.4.0-beta.2" - "@0x/base-contract" "^5.5.0-beta.2" - "@0x/contract-addresses" "^3.3.0-beta.3" + "@0x/abi-gen-wrappers" "^5.4.0-beta.3" + "@0x/base-contract" "^5.5.0-beta.3" + "@0x/contract-addresses" "^3.3.0-beta.4" "@0x/contract-artifacts" "^2.3.0-beta.3" - "@0x/order-utils" "^8.5.0-beta.2" + "@0x/order-utils" "^8.5.0-beta.3" ethers "~4.0.4" http-status-codes "^1.3.2" "@0x/contract-wrappers@^12.2.0-beta.4": version "12.2.0-beta.4" resolved "https://registry.yarnpkg.com/@0x/contract-wrappers/-/contract-wrappers-12.2.0-beta.4.tgz#7a7301dd50c28887879df4d385e80a49e040748d" - integrity sha512-JVoYG3Rd430fZw9ogBSqeLOaJXkqp9N7g614X5/bzzuG/dSDdwXl48X02m66aGFWcNofx/iMsT4tpOZrJ2bDBg== dependencies: "@0x/assert" "^2.2.0-beta.3" "@0x/base-contract" "^5.5.0-beta.4" @@ -741,32 +735,31 @@ ethereum-types "^2.2.0-beta.2" ethers "~4.0.4" -"@0x/contracts-dev-utils@^0.1.0-beta.2": +"@0x/contracts-dev-utils@^0.1.0-beta.3": version "0.1.0-beta.4" resolved "https://registry.yarnpkg.com/@0x/contracts-dev-utils/-/contracts-dev-utils-0.1.0-beta.4.tgz#87f51a7ed778b619beb8b32bf08ea6b3e4495d4e" - integrity sha512-6fQ13/L8aKKnO/vs2WIg0D7FXz3QpMKBHrTYdzvpwFrOcd6MPavQEj0KCQdT/4aplMvWnWDSVAOqn8i/lJJ8jQ== dependencies: "@0x/base-contract" "^5.5.0-beta.4" -"@0x/contracts-erc20@2.3.0-beta.2": - version "2.3.0-beta.2" - resolved "https://registry.yarnpkg.com/@0x/contracts-erc20/-/contracts-erc20-2.3.0-beta.2.tgz#218239f5594fdbbf8c1ff757a6356ac6fb787421" +"@0x/contracts-erc20@2.3.0-beta.3": + version "2.3.0-beta.3" + resolved "https://registry.yarnpkg.com/@0x/contracts-erc20/-/contracts-erc20-2.3.0-beta.3.tgz#744f911d340576a27253b5961d52b09bb8659a98" dependencies: - "@0x/base-contract" "^5.5.0-beta.2" + "@0x/base-contract" "^5.5.0-beta.3" "@0x/types" "^2.5.0-beta.2" "@0x/typescript-typings" "^4.4.0-beta.2" ethereum-types "^2.2.0-beta.2" -"@0x/coordinator-server@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@0x/coordinator-server/-/coordinator-server-1.0.3.tgz#736640edc5960bd65674436f96050fd7b4da7ac3" +"@0x/coordinator-server@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@0x/coordinator-server/-/coordinator-server-1.0.4.tgz#9729ce789fb772a5ae0a8dcdf5928de9e80ac1af" dependencies: "@0x/assert" "2.2.0-beta.2" - "@0x/contract-addresses" "3.3.0-beta.3" - "@0x/contract-wrappers" "12.2.0-beta.2" - "@0x/contracts-erc20" "2.3.0-beta.2" + "@0x/contract-addresses" "3.3.0-beta.4" + "@0x/contract-wrappers" "12.2.0-beta.3" + "@0x/contracts-erc20" "2.3.0-beta.3" "@0x/json-schemas" "4.1.0-beta.2" - "@0x/order-utils" "8.5.0-beta.2" + "@0x/order-utils" "8.5.0-beta.3" "@0x/subproviders" "5.1.0-beta.2" "@0x/types" "2.5.0-beta.2" "@0x/typescript-typings" "4.4.0-beta.2" @@ -789,7 +782,6 @@ "@0x/json-schemas@4.1.0-beta.2": version "4.1.0-beta.2" resolved "https://registry.yarnpkg.com/@0x/json-schemas/-/json-schemas-4.1.0-beta.2.tgz#79d05d0c91525e2356f783dae5e572dd3624969f" - integrity sha512-GWLAC4GlcRcn3ct+0wV/ppey+M9bnfnznB1fFcBWS7qmjM0iq36ex3DP48MJroWLWwUiXIWHrAZkp5QCAlc3FA== dependencies: "@0x/typescript-typings" "^4.4.0-beta.2" "@types/node" "*" @@ -799,7 +791,6 @@ "@0x/json-schemas@^4.1.0-beta.2", "@0x/json-schemas@^4.1.0-beta.3": version "4.1.0-beta.3" resolved "https://registry.yarnpkg.com/@0x/json-schemas/-/json-schemas-4.1.0-beta.3.tgz#af70a35691108ea162140640bae93a7fc84ca6ee" - integrity sha512-vcgzSeaOXiUQ4KjqdLTTBHbkWnp4IE7cXbUblRy8Y0XYPQsPywhs9mtjY4lBVNmm1DDpLhreo1mwrvPS3HW5YA== dependencies: "@0x/typescript-typings" "^4.4.0-beta.2" "@types/node" "*" @@ -819,15 +810,15 @@ uuid "^3.3.2" websocket "^1.0.29" -"@0x/order-utils@8.5.0-beta.2": - version "8.5.0-beta.2" - resolved "https://registry.yarnpkg.com/@0x/order-utils/-/order-utils-8.5.0-beta.2.tgz#ffd3da985e79aab4d0308ab33e399ec51c835ec1" +"@0x/order-utils@8.5.0-beta.3": + version "8.5.0-beta.3" + resolved "https://registry.yarnpkg.com/@0x/order-utils/-/order-utils-8.5.0-beta.3.tgz#67bc733cf64cb7cc5653a913e986c5f211b1b7d2" dependencies: - "@0x/abi-gen-wrappers" "^5.4.0-beta.2" + "@0x/abi-gen-wrappers" "^5.4.0-beta.3" "@0x/assert" "^2.2.0-beta.2" - "@0x/contract-addresses" "^3.3.0-beta.3" + "@0x/contract-addresses" "^3.3.0-beta.4" "@0x/contract-artifacts" "^2.3.0-beta.3" - "@0x/contracts-dev-utils" "^0.1.0-beta.2" + "@0x/contracts-dev-utils" "^0.1.0-beta.3" "@0x/json-schemas" "^4.1.0-beta.2" "@0x/types" "^2.5.0-beta.2" "@0x/typescript-typings" "^4.4.0-beta.2" @@ -841,10 +832,9 @@ ethers "~4.0.4" lodash "^4.17.11" -"@0x/order-utils@^8.5.0-beta.2": +"@0x/order-utils@^8.5.0-beta.3": version "8.5.0-beta.4" resolved "https://registry.yarnpkg.com/@0x/order-utils/-/order-utils-8.5.0-beta.4.tgz#900387631008cc9dc9ece125d28450d2beaea462" - integrity sha512-a3vFDAETaPVo/hN5iFr1gxgshfSzAO23NnaUSjeEhs4Ff8eKxuISc6UARFaNzdQeXygDWHMjwlmZ7iegBHe93g== dependencies: "@0x/assert" "^2.2.0-beta.3" "@0x/contract-wrappers" "^12.2.0-beta.4" @@ -858,7 +848,6 @@ "@0x/subproviders@5.1.0-beta.2": version "5.1.0-beta.2" resolved "https://registry.yarnpkg.com/@0x/subproviders/-/subproviders-5.1.0-beta.2.tgz#020369711330755448397b3b8cecf2868ae7c54c" - integrity sha512-Nk8iSlR95Zo6L1tq2tHLKupX5bCD/NlxQ/KKli4qyAawyxuXQcQbl8flUApJFd+BYY7mghLDwY5u4o8CCR56Nw== dependencies: "@0x/assert" "^2.2.0-beta.2" "@0x/types" "^2.5.0-beta.2" @@ -899,7 +888,6 @@ "@0x/types@2.5.0-beta.2": version "2.5.0-beta.2" resolved "https://registry.yarnpkg.com/@0x/types/-/types-2.5.0-beta.2.tgz#19d8bda61d5c1b1febc569d30dc8e7bf764d38f9" - integrity sha512-/7+n09z1dngIN7Kw7L+nleGe0+YXCT4O0VzTihZj6Z2vVHCt+Wo4q1ma9r11vviv07tmqglyw7QbYAfTHIz8Ew== dependencies: "@types/node" "*" bignumber.js "~9.0.0" @@ -916,7 +904,6 @@ "@0x/types@^2.5.0-beta.2", "@0x/types@^2.5.0-beta.3": version "2.5.0-beta.3" resolved "https://registry.yarnpkg.com/@0x/types/-/types-2.5.0-beta.3.tgz#e010e9dbf62e37e59177c1d6df8d1acf3a9ea1b4" - integrity sha512-5wJs4/EZGPcU6W5IZ87zuya9vQUPD4DchyP29bXyguGHg9dOxuUOF4WauJZExWlPCS7eivviiUHpZD9DZhni+w== dependencies: "@types/node" "*" bignumber.js "~9.0.0" @@ -925,7 +912,6 @@ "@0x/typescript-typings@4.4.0-beta.2", "@0x/typescript-typings@^4.4.0-beta.2": version "4.4.0-beta.2" resolved "https://registry.yarnpkg.com/@0x/typescript-typings/-/typescript-typings-4.4.0-beta.2.tgz#67c621252f162914186b8f684ac5e306206c1cf2" - integrity sha512-Fq2nOKvopdLMEjuPiKqomGog06bxAXGjqnodCwv9OKr11V5W1twFTUM3c1TENfHeGvcqf1aMl1hsH3fuVP61jg== dependencies: "@types/bn.js" "^4.11.0" "@types/react" "*" @@ -946,7 +932,6 @@ "@0x/utils@4.6.0-beta.2": version "4.6.0-beta.2" resolved "https://registry.yarnpkg.com/@0x/utils/-/utils-4.6.0-beta.2.tgz#ffa70f05736a74ac8d7ca5debe01bff7e6d8f073" - integrity sha512-HjewJF4Ibsizh6oWZZxdVxeNc9mGgjdwTCVp/Xj2k9GN6GI8m8EKiowk4Db86wG0/B6y0PDK+985rZ3dtc3MLQ== dependencies: "@0x/types" "^2.5.0-beta.2" "@0x/typescript-typings" "^4.4.0-beta.2" @@ -983,7 +968,6 @@ "@0x/utils@^4.6.0-beta.2", "@0x/utils@^4.6.0-beta.3": version "4.6.0-beta.3" resolved "https://registry.yarnpkg.com/@0x/utils/-/utils-4.6.0-beta.3.tgz#d40278916d98c48ea05821ae4987c88f032c7bff" - integrity sha512-aPIUgfhaDhwgddJAlIQJ2Ki87A60ovatBLCjareLUbsQSvFS5i3iujUBQHgFxZAv9tgl35fyg2ISEJ1YkQyubA== dependencies: "@0x/types" "^2.5.0-beta.3" "@0x/typescript-typings" "^4.4.0-beta.2" @@ -1018,7 +1002,6 @@ "@0x/web3-wrapper@6.1.0-beta.2": version "6.1.0-beta.2" resolved "https://registry.yarnpkg.com/@0x/web3-wrapper/-/web3-wrapper-6.1.0-beta.2.tgz#24aae8a0063057ebb6d3a7893a01d0abac8cd19c" - integrity sha512-XTurMsspRe089KybRbaEDUce/p25LjHBuGh5zMWb6OWctIoD7iJ2QHJOoH5AMJMlXObTO3CFwpwybbDmlbaKGQ== dependencies: "@0x/assert" "^2.2.0-beta.2" "@0x/json-schemas" "^4.1.0-beta.2" @@ -1032,7 +1015,6 @@ "@0x/web3-wrapper@^6.1.0-beta.2", "@0x/web3-wrapper@^6.1.0-beta.3": version "6.1.0-beta.3" resolved "https://registry.yarnpkg.com/@0x/web3-wrapper/-/web3-wrapper-6.1.0-beta.3.tgz#82161147e9283391e0c7cd6027c971749c5a2f77" - integrity sha512-mc8120n8w88gICbDm8pkmC83Ul3RgE4BGsjY5BRBFefmKbv/XLeBZiWdhsaWYmkk8v4f+ZxAQ+HHTBDsRH87Og== dependencies: "@0x/assert" "^2.2.0-beta.3" "@0x/json-schemas" "^4.1.0-beta.3" @@ -6768,7 +6750,6 @@ ethereum-types@^2.1.6: ethereum-types@^2.2.0-beta.2: version "2.2.0-beta.2" resolved "https://registry.yarnpkg.com/ethereum-types/-/ethereum-types-2.2.0-beta.2.tgz#0b446842474c2afacd351258ed4a2d0841f2608f" - integrity sha512-5ANYHI/InHqf4Nt8oYrpvcph9/D6gi3sbM7Rlr8r0QjXb2mqocqEvOH460Zkf1robc7WDqurp9baeMy+um8kww== dependencies: "@types/node" "*" bignumber.js "~9.0.0"