Fixed the bug and moved "contracts-tests" to "contracts-integrations"

This commit is contained in:
Alex Towle 2019-12-17 17:17:54 -08:00
parent 51ca3109eb
commit 47c3ed9705
25 changed files with 436 additions and 544 deletions

View File

@ -7,7 +7,7 @@
"evmVersion": "constantinople", "evmVersion": "constantinople",
"optimizer": { "optimizer": {
"enabled": true, "enabled": true,
"runs": 1666, "runs": 200,
"details": { "yul": true, "deduplicate": true, "cse": true, "constantOptimizer": true } "details": { "yul": true, "deduplicate": true, "cse": true, "constantOptimizer": true }
}, },
"outputSelection": { "outputSelection": {

View File

@ -35,8 +35,8 @@ contract DevUtils is
OrderValidationUtils, OrderValidationUtils,
LibTransactionDecoder, LibTransactionDecoder,
LibEIP712ExchangeDomain, LibEIP712ExchangeDomain,
EthBalanceChecker, EthBalanceChecker
OrderTransferSimulationUtils // OrderTransferSimulationUtils
{ {
constructor (address _exchange) constructor (address _exchange)
public public

View File

@ -31,6 +31,8 @@ import "@0x/contracts-utils/contracts/src/LibBytes.sol";
contract OrderTransferSimulationUtils is contract OrderTransferSimulationUtils is
LibExchangeRichErrorDecoder LibExchangeRichErrorDecoder
{ {
bool second;
using LibBytes for bytes; using LibBytes for bytes;
enum OrderTransferResults { enum OrderTransferResults {
@ -54,6 +56,52 @@ contract OrderTransferSimulationUtils is
_EXCHANGE = IExchange(_exchange); _EXCHANGE = IExchange(_exchange);
} }
/// @dev Simulates the maker transfers within an order and returns the index of the first failed transfer.
/// @param order The order to simulate transfers for.
/// @param takerAddress The address of the taker that will fill the order.
/// @param takerAssetFillAmount The amount of takerAsset that the taker wished to fill.
/// @return The index of the first failed transfer (or 4 if all transfers are successful).
function getSimulatedOrderMakerTransferResults(
LibOrder.Order memory order,
address takerAddress,
uint256 takerAssetFillAmount
)
public
returns (OrderTransferResults orderTransferResults)
{
LibFillResults.FillResults memory fillResults = LibFillResults.calculateFillResultsTrace(
order,
takerAssetFillAmount,
_EXCHANGE.protocolFeeMultiplier(),
tx.gasprice,
second
);
bytes[] memory assetData = new bytes[](2);
address[] memory fromAddresses = new address[](2);
address[] memory toAddresses = new address[](2);
uint256[] memory amounts = new uint256[](2);
// Transfer `makerAsset` from maker to taker
assetData[0] = order.makerAssetData;
fromAddresses[0] = order.makerAddress;
toAddresses[0] = takerAddress;
amounts[0] = fillResults.makerAssetFilledAmount;
// Transfer `makerFeeAsset` from maker to feeRecipient
assetData[1] = order.makerFeeAssetData;
fromAddresses[1] = order.makerAddress;
toAddresses[1] = order.feeRecipientAddress;
amounts[1] = fillResults.makerFeePaid;
return _simulateTransferFromCalls(
assetData,
fromAddresses,
toAddresses,
amounts
);
}
/// @dev Simulates all of the transfers within an order and returns the index of the first failed transfer. /// @dev Simulates all of the transfers within an order and returns the index of the first failed transfer.
/// @param order The order to simulate transfers for. /// @param order The order to simulate transfers for.
/// @param takerAddress The address of the taker that will fill the order. /// @param takerAddress The address of the taker that will fill the order.
@ -104,6 +152,54 @@ contract OrderTransferSimulationUtils is
toAddresses[3] = order.feeRecipientAddress; toAddresses[3] = order.feeRecipientAddress;
amounts[3] = fillResults.makerFeePaid; amounts[3] = fillResults.makerFeePaid;
return _simulateTransferFromCalls(
assetData,
fromAddresses,
toAddresses,
amounts
);
}
/// @dev Simulates all of the transfers for each given order and returns the indices of each first failed transfer.
/// @param orders Array of orders to individually simulate transfers for.
/// @param takerAddresses Array of addresses of takers that will fill each order.
/// @param takerAssetFillAmounts Array of amounts of takerAsset that will be filled for each order.
/// @return The indices of the first failed transfer (or 4 if all transfers are successful) for each order.
function getSimulatedOrdersTransferResults(
LibOrder.Order[] memory orders,
address[] memory takerAddresses,
uint256[] memory takerAssetFillAmounts
)
public
returns (OrderTransferResults[] memory orderTransferResults)
{
uint256 length = orders.length;
orderTransferResults = new OrderTransferResults[](length);
for (uint256 i = 0; i != length; i++) {
orderTransferResults[i] = getSimulatedOrderTransferResults(
orders[i],
takerAddresses[i],
takerAssetFillAmounts[i]
);
}
return orderTransferResults;
}
/// @dev Makes the simulation call with information about the transfers and processes
/// the returndata.
/// @param assetData The assetdata to use to make transfers.
/// @param fromAddresses The addresses to transfer funds.
/// @param toAddresses The addresses that will receive funds
/// @param amounts The amounts involved in the transfer.
function _simulateTransferFromCalls(
bytes[] memory assetData,
address[] memory fromAddresses,
address[] memory toAddresses,
uint256[] memory amounts
)
internal
returns (OrderTransferResults orderTransferResults)
{
// Encode data for `simulateDispatchTransferFromCalls(assetData, fromAddresses, toAddresses, amounts)` // Encode data for `simulateDispatchTransferFromCalls(assetData, fromAddresses, toAddresses, amounts)`
bytes memory simulateDispatchTransferFromCallsData = abi.encodeWithSelector( bytes memory simulateDispatchTransferFromCallsData = abi.encodeWithSelector(
IExchange(address(0)).simulateDispatchTransferFromCalls.selector, IExchange(address(0)).simulateDispatchTransferFromCalls.selector,
@ -132,29 +228,4 @@ contract OrderTransferSimulationUtils is
revert("UNKNOWN_RETURN_DATA"); revert("UNKNOWN_RETURN_DATA");
} }
} }
/// @dev Simulates all of the transfers for each given order and returns the indices of each first failed transfer.
/// @param orders Array of orders to individually simulate transfers for.
/// @param takerAddresses Array of addresses of takers that will fill each order.
/// @param takerAssetFillAmounts Array of amounts of takerAsset that will be filled for each order.
/// @return The indices of the first failed transfer (or 4 if all transfers are successful) for each order.
function getSimulatedOrdersTransferResults(
LibOrder.Order[] memory orders,
address[] memory takerAddresses,
uint256[] memory takerAssetFillAmounts
)
public
returns (OrderTransferResults[] memory orderTransferResults)
{
uint256 length = orders.length;
orderTransferResults = new OrderTransferResults[](length);
for (uint256 i = 0; i != length; i++) {
orderTransferResults[i] = getSimulatedOrderTransferResults(
orders[i],
takerAddresses[i],
takerAssetFillAmounts[i]
);
}
return orderTransferResults;
}
} }

View File

@ -25,10 +25,12 @@ import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol";
import "@0x/contracts-utils/contracts/src/LibBytes.sol"; import "@0x/contracts-utils/contracts/src/LibBytes.sol";
import "@0x/contracts-utils/contracts/src/LibSafeMath.sol"; import "@0x/contracts-utils/contracts/src/LibSafeMath.sol";
import "./LibAssetData.sol"; import "./LibAssetData.sol";
import "./OrderTransferSimulationUtils.sol";
contract OrderValidationUtils is contract OrderValidationUtils is
LibAssetData LibAssetData,
OrderTransferSimulationUtils
{ {
using LibBytes for bytes; using LibBytes for bytes;
using LibSafeMath for uint256; using LibSafeMath for uint256;
@ -50,7 +52,6 @@ contract OrderValidationUtils is
/// amount of each asset that can be filled. /// amount of each asset that can be filled.
function getOrderRelevantState(LibOrder.Order memory order, bytes memory signature) function getOrderRelevantState(LibOrder.Order memory order, bytes memory signature)
public public
view
returns ( returns (
LibOrder.OrderInfo memory orderInfo, LibOrder.OrderInfo memory orderInfo,
uint256 fillableTakerAssetAmount, uint256 fillableTakerAssetAmount,
@ -99,7 +100,6 @@ contract OrderValidationUtils is
} else { } else {
// Get the transferable amount of the `makerFeeAsset` // Get the transferable amount of the `makerFeeAsset`
uint256 transferableMakerFeeAssetAmount = getTransferableAssetAmount(makerAddress, order.makerFeeAssetData); uint256 transferableMakerFeeAssetAmount = getTransferableAssetAmount(makerAddress, order.makerFeeAssetData);
uint256 transferableMakerToTakerAmount = LibMath.getPartialAmountFloor( uint256 transferableMakerToTakerAmount = LibMath.getPartialAmountFloor(
transferableMakerAssetAmount, transferableMakerAssetAmount,
order.makerAssetAmount, order.makerAssetAmount,
@ -120,6 +120,13 @@ contract OrderValidationUtils is
transferableTakerAssetAmount transferableTakerAssetAmount
); );
// Execute the maker transfers.
fillableTakerAssetAmount = getSimulatedOrderMakerTransferResults(
order,
order.takerAddress,
fillableTakerAssetAmount
) == OrderTransferResults.TransfersSuccessful ? fillableTakerAssetAmount : 0;
return (orderInfo, fillableTakerAssetAmount, isValidSignature); return (orderInfo, fillableTakerAssetAmount, isValidSignature);
} }
@ -135,7 +142,6 @@ contract OrderValidationUtils is
/// the `takerAssetData` to get the final amount of each asset that can be filled. /// the `takerAssetData` to get the final amount of each asset that can be filled.
function getOrderRelevantStates(LibOrder.Order[] memory orders, bytes[] memory signatures) function getOrderRelevantStates(LibOrder.Order[] memory orders, bytes[] memory signatures)
public public
view
returns ( returns (
LibOrder.OrderInfo[] memory ordersInfo, LibOrder.OrderInfo[] memory ordersInfo,
uint256[] memory fillableTakerAssetAmounts, uint256[] memory fillableTakerAssetAmounts,
@ -148,6 +154,10 @@ contract OrderValidationUtils is
isValidSignature = new bool[](length); isValidSignature = new bool[](length);
for (uint256 i = 0; i != length; i++) { for (uint256 i = 0; i != length; i++) {
if (i == 1) {
second = true;
}
(ordersInfo[i], fillableTakerAssetAmounts[i], isValidSignature[i]) = getOrderRelevantState( (ordersInfo[i], fillableTakerAssetAmounts[i], isValidSignature[i]) = getOrderRelevantState(
orders[i], orders[i],
signatures[i] signatures[i]

View File

@ -8,7 +8,7 @@
"main": "lib/src/index.js", "main": "lib/src/index.js",
"scripts": { "scripts": {
"build": "yarn pre_build && tsc -b", "build": "yarn pre_build && tsc -b",
"test": "yarn assert_deployable && echo !!! Tests are run via @0x/contracts-tests !!!", "test": "yarn assert_deployable && echo !!! Tests are run via @0x/contracts-integrations !!!",
"assert_deployable": "node -e \"const bytecodeLen = (require('./generated-artifacts/DevUtils.json').compilerOutput.evm.bytecode.object.length-2)/2; assert(bytecodeLen<=0x6000,'DevUtils contract is too big to deploy, per EIP-170. '+bytecodeLen+'>'+0x6000)\"", "assert_deployable": "node -e \"const bytecodeLen = (require('./generated-artifacts/DevUtils.json').compilerOutput.evm.bytecode.object.length-2)/2; assert(bytecodeLen<=0x6000,'DevUtils contract is too big to deploy, per EIP-170. '+bytecodeLen+'>'+0x6000)\"",
"build:ci": "yarn build", "build:ci": "yarn build",
"pre_build": "run-s compile quantify_bytecode contracts:gen generate_contract_wrappers contracts:copy", "pre_build": "run-s compile quantify_bytecode contracts:gen generate_contract_wrappers contracts:copy",

View File

@ -49,6 +49,51 @@ library LibFillResults {
uint256 profitInRightMakerAsset; // Profit taken from the right maker uint256 profitInRightMakerAsset; // Profit taken from the right maker
} }
event TestEvent(string file_name, string value_name, uint256 value);
/// FIXME: Remove this function after investigation
/// @dev Calculates amounts filled and fees paid by maker and taker.
/// @param order to be filled.
/// @param takerAssetFilledAmount Amount of takerAsset that will be filled.
/// @param protocolFeeMultiplier The current protocol fee of the exchange contract.
/// @param gasPrice The gasprice of the transaction. This is provided so that the function call can continue
/// to be pure rather than view.
/// @return fillResults Amounts filled and fees paid by maker and taker.
function calculateFillResultsTrace(
LibOrder.Order memory order,
uint256 takerAssetFilledAmount,
uint256 protocolFeeMultiplier,
uint256 gasPrice,
bool shouldTrace
)
internal
pure
returns (FillResults memory fillResults)
{
// Compute proportional transfer amounts
fillResults.takerAssetFilledAmount = takerAssetFilledAmount;
fillResults.makerAssetFilledAmount = LibMath.safeGetPartialAmountFloor(
takerAssetFilledAmount,
order.takerAssetAmount,
order.makerAssetAmount
);
fillResults.makerFeePaid = LibMath.safeGetPartialAmountFloor(
takerAssetFilledAmount,
order.takerAssetAmount,
order.makerFee
);
fillResults.takerFeePaid = LibMath.safeGetPartialAmountFloor(
takerAssetFilledAmount,
order.takerAssetAmount,
order.takerFee
);
// Compute the protocol fee that should be paid for a single fill.
fillResults.protocolFeePaid = gasPrice.safeMul(protocolFeeMultiplier);
return fillResults;
}
/// @dev Calculates amounts filled and fees paid by maker and taker. /// @dev Calculates amounts filled and fees paid by maker and taker.
/// @param order to be filled. /// @param order to be filled.
/// @param takerAssetFilledAmount Amount of takerAsset that will be filled. /// @param takerAssetFilledAmount Amount of takerAsset that will be filled.

View File

@ -102,6 +102,7 @@
"@0x/typescript-typings": "^5.0.1", "@0x/typescript-typings": "^5.0.1",
"@0x/utils": "^5.1.1", "@0x/utils": "^5.1.1",
"ethereum-types": "^3.0.0", "ethereum-types": "^3.0.0",
"ethereumjs-util": "^6.2.0",
"lodash": "^4.17.11" "lodash": "^4.17.11"
}, },
"publishConfig": { "publishConfig": {

View File

@ -0,0 +1,45 @@
import { artifacts, DevUtilsContract } from '@0x/contracts-dev-utils';
import { blockchainTests, constants, expect } from '@0x/contracts-test-utils';
import { Order } from '@0x/types';
import { BigNumber } from '@0x/utils';
blockchainTests('DevUtils.getOrderHash', env => {
let devUtils: DevUtilsContract;
before(async () => {
devUtils = await DevUtilsContract.deployFrom0xArtifactAsync(
artifacts.DevUtils,
env.provider,
env.txDefaults,
artifacts,
constants.NULL_ADDRESS,
);
});
it('should return the order hash', async () => {
const expectedOrderHash = '0x331cb7e07a757bae130702da6646c26531798c92bcfaf671817268fd2c188531';
const exchangeAddress = '0x1dc4c1cefef38a777b15aa20260a54e584b16c48';
const chainId = 50;
const order: Order = {
makerAddress: constants.NULL_ADDRESS,
takerAddress: constants.NULL_ADDRESS,
senderAddress: constants.NULL_ADDRESS,
feeRecipientAddress: constants.NULL_ADDRESS,
makerAssetData: constants.NULL_ADDRESS,
takerAssetData: constants.NULL_ADDRESS,
makerFeeAssetData: constants.NULL_ADDRESS,
takerFeeAssetData: constants.NULL_ADDRESS,
salt: new BigNumber(0),
makerFee: new BigNumber(0),
takerFee: new BigNumber(0),
makerAssetAmount: new BigNumber(0),
takerAssetAmount: new BigNumber(0),
expirationTimeSeconds: new BigNumber(0),
exchangeAddress,
chainId,
};
expect(await devUtils.getOrderHash(order, new BigNumber(chainId), exchangeAddress).callAsync()).to.be.equal(
expectedOrderHash,
);
});
});

View File

@ -1,6 +1,5 @@
import * as chai from 'chai';
import { LogWithDecodedArgs } from 'ethereum-types';
import * as crypto from 'crypto'; import * as crypto from 'crypto';
import { LogWithDecodedArgs } from 'ethereum-types';
import { import {
artifacts as proxyArtifacts, artifacts as proxyArtifacts,
@ -19,19 +18,13 @@ import {
import { artifacts as erc20Artifacts, DummyERC20TokenContract } from '@0x/contracts-erc20'; import { artifacts as erc20Artifacts, DummyERC20TokenContract } from '@0x/contracts-erc20';
import { artifacts as erc721Artifacts, DummyERC721TokenContract } from '@0x/contracts-erc721'; import { artifacts as erc721Artifacts, DummyERC721TokenContract } from '@0x/contracts-erc721';
import { artifacts as exchangeArtifacts, ExchangeContract } from '@0x/contracts-exchange'; import { artifacts as exchangeArtifacts, ExchangeContract } from '@0x/contracts-exchange';
import { chaiSetup, constants, LogDecoder, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils'; import { blockchainTests, constants, expect, LogDecoder } from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { AssetProxyId } from '@0x/types'; import { AssetProxyId } from '@0x/types';
import { BigNumber, providerUtils, StringRevertError, LibBytesRevertErrors } from '@0x/utils'; import { BigNumber, LibBytesRevertErrors, StringRevertError } from '@0x/utils';
import * as ethUtil from 'ethereumjs-util'; import * as ethUtil from 'ethereumjs-util';
import { artifacts, LibAssetDataContract } from '@0x/contracts-dev-utils'; import { artifacts, LibAssetDataContract } from '@0x/contracts-dev-utils';
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
const KNOWN_ERC20_ENCODING = { const KNOWN_ERC20_ENCODING = {
address: '0x1dc4c1cefef38a777b15aa20260a54e584b16c48', address: '0x1dc4c1cefef38a777b15aa20260a54e584b16c48',
assetData: '0xf47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48', assetData: '0xf47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48',
@ -69,7 +62,8 @@ const KNOWN_STATIC_CALL_ENCODING = {
'0xc339d10a0000000000000000000000006dfff22588be9b3ef8cf0ad6dc9b84796f9fb45f0000000000000000000000000000000000000000000000000000000000000060b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60000000000000000000000000000000000000000000000000000000000000024ed2cfc9c000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000', '0xc339d10a0000000000000000000000006dfff22588be9b3ef8cf0ad6dc9b84796f9fb45f0000000000000000000000000000000000000000000000000000000000000060b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60000000000000000000000000000000000000000000000000000000000000024ed2cfc9c000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000',
}; };
describe('LibAssetData', () => { // TODO(jalextowle): This file could really be cleaned up by using the DeploymentManager tool.
blockchainTests('LibAssetData', env => {
let exchange: ExchangeContract; let exchange: ExchangeContract;
let erc20Proxy: ERC20ProxyContract; let erc20Proxy: ERC20ProxyContract;
let erc721Proxy: ERC721ProxyContract; let erc721Proxy: ERC721ProxyContract;
@ -93,44 +87,43 @@ describe('LibAssetData', () => {
let erc1155TokenId: BigNumber; let erc1155TokenId: BigNumber;
before(async () => { before(async () => {
await blockchainLifecycle.startAsync(); const chainId = await env.getChainIdAsync();
const chainId = await providerUtils.getChainIdAsync(provider);
exchange = await ExchangeContract.deployFrom0xArtifactAsync( exchange = await ExchangeContract.deployFrom0xArtifactAsync(
exchangeArtifacts.Exchange, exchangeArtifacts.Exchange,
provider, env.provider,
txDefaults, env.txDefaults,
{}, {},
new BigNumber(chainId), new BigNumber(chainId),
); );
erc20Proxy = await ERC20ProxyContract.deployFrom0xArtifactAsync( erc20Proxy = await ERC20ProxyContract.deployFrom0xArtifactAsync(
proxyArtifacts.ERC20Proxy, proxyArtifacts.ERC20Proxy,
provider, env.provider,
txDefaults, env.txDefaults,
artifacts, artifacts,
); );
erc721Proxy = await ERC721ProxyContract.deployFrom0xArtifactAsync( erc721Proxy = await ERC721ProxyContract.deployFrom0xArtifactAsync(
proxyArtifacts.ERC721Proxy, proxyArtifacts.ERC721Proxy,
provider, env.provider,
txDefaults, env.txDefaults,
artifacts, artifacts,
); );
erc1155Proxy = await ERC1155ProxyContract.deployFrom0xArtifactAsync( erc1155Proxy = await ERC1155ProxyContract.deployFrom0xArtifactAsync(
proxyArtifacts.ERC1155Proxy, proxyArtifacts.ERC1155Proxy,
provider, env.provider,
txDefaults, env.txDefaults,
artifacts, artifacts,
); );
multiAssetProxy = await MultiAssetProxyContract.deployFrom0xArtifactAsync( multiAssetProxy = await MultiAssetProxyContract.deployFrom0xArtifactAsync(
proxyArtifacts.MultiAssetProxy, proxyArtifacts.MultiAssetProxy,
provider, env.provider,
txDefaults, env.txDefaults,
artifacts, artifacts,
); );
staticCallProxy = await StaticCallProxyContract.deployFrom0xArtifactAsync( staticCallProxy = await StaticCallProxyContract.deployFrom0xArtifactAsync(
proxyArtifacts.StaticCallProxy, proxyArtifacts.StaticCallProxy,
provider, env.provider,
txDefaults, env.txDefaults,
artifacts, artifacts,
); );
@ -142,25 +135,25 @@ describe('LibAssetData', () => {
libAssetData = await LibAssetDataContract.deployFrom0xArtifactAsync( libAssetData = await LibAssetDataContract.deployFrom0xArtifactAsync(
artifacts.LibAssetData, artifacts.LibAssetData,
provider, env.provider,
txDefaults, env.txDefaults,
artifacts, artifacts,
exchange.address, exchange.address,
); );
staticCallTarget = await TestStaticCallTargetContract.deployFrom0xArtifactAsync( staticCallTarget = await TestStaticCallTargetContract.deployFrom0xArtifactAsync(
proxyArtifacts.TestStaticCallTarget, proxyArtifacts.TestStaticCallTarget,
provider, env.provider,
txDefaults, env.txDefaults,
artifacts, artifacts,
); );
[tokenOwnerAddress] = await web3Wrapper.getAvailableAddressesAsync(); [tokenOwnerAddress] = await env.getAccountAddressesAsync();
erc20Token = await DummyERC20TokenContract.deployFrom0xArtifactAsync( erc20Token = await DummyERC20TokenContract.deployFrom0xArtifactAsync(
erc20Artifacts.DummyERC20Token, erc20Artifacts.DummyERC20Token,
provider, env.provider,
txDefaults, env.txDefaults,
artifacts, artifacts,
'Dummy', 'Dummy',
'DUM', 'DUM',
@ -170,8 +163,8 @@ describe('LibAssetData', () => {
erc721Token = await DummyERC721TokenContract.deployFrom0xArtifactAsync( erc721Token = await DummyERC721TokenContract.deployFrom0xArtifactAsync(
erc721Artifacts.DummyERC721Token, erc721Artifacts.DummyERC721Token,
provider, env.provider,
txDefaults, env.txDefaults,
artifacts, artifacts,
'Dummy', 'Dummy',
'DUM', 'DUM',
@ -187,12 +180,12 @@ describe('LibAssetData', () => {
erc1155Token = await ERC1155MintableContract.deployFrom0xArtifactAsync( erc1155Token = await ERC1155MintableContract.deployFrom0xArtifactAsync(
erc1155Artifacts.ERC1155Mintable, erc1155Artifacts.ERC1155Mintable,
provider, env.provider,
txDefaults, env.txDefaults,
artifacts, artifacts,
); );
const logDecoder = new LogDecoder(web3Wrapper, erc1155Artifacts); const logDecoder = new LogDecoder(env.web3Wrapper, erc1155Artifacts);
const transactionReceipt = await logDecoder.getTxWithDecodedLogsAsync( const transactionReceipt = await logDecoder.getTxWithDecodedLogsAsync(
await erc1155Token.create('uri:Dummy', /*isNonFungible:*/ false).sendTransactionAsync(), await erc1155Token.create('uri:Dummy', /*isNonFungible:*/ false).sendTransactionAsync(),
); );
@ -204,17 +197,6 @@ describe('LibAssetData', () => {
.awaitTransactionSuccessAsync(); .awaitTransactionSuccessAsync();
}); });
after(async () => {
await blockchainLifecycle.revertAsync();
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
});
afterEach(async () => {
await blockchainLifecycle.revertAsync();
});
it('should have a deployed-to address', () => { it('should have a deployed-to address', () => {
expect(libAssetData.address.slice(0, 2)).to.equal('0x'); expect(libAssetData.address.slice(0, 2)).to.equal('0x');
}); });
@ -345,7 +327,7 @@ describe('LibAssetData', () => {
}); });
it('should revert for invalid assetProxyId', async () => { it('should revert for invalid assetProxyId', async () => {
const badAssetData = '0x' + crypto.randomBytes(4).toString('hex') + constants.NULL_ADDRESS; const badAssetData = `0x${crypto.randomBytes(4).toString('hex')}${constants.NULL_ADDRESS}`;
await expect(libAssetData.revertIfInvalidAssetData(badAssetData).callAsync()).to.eventually.be.rejectedWith( await expect(libAssetData.revertIfInvalidAssetData(badAssetData).callAsync()).to.eventually.be.rejectedWith(
StringRevertError, StringRevertError,
); );

View File

@ -1,161 +1,94 @@
import { import { ERC20ProxyContract } from '@0x/contracts-asset-proxy';
artifacts as proxyArtifacts, import { DevUtilsContract } from '@0x/contracts-dev-utils';
ERC20ProxyContract,
ERC20Wrapper,
ERC721ProxyContract,
ERC721Wrapper,
MultiAssetProxyContract,
} from '@0x/contracts-asset-proxy';
import { DummyERC20TokenContract } from '@0x/contracts-erc20'; import { DummyERC20TokenContract } from '@0x/contracts-erc20';
import { DummyERC721TokenContract } from '@0x/contracts-erc721'; import { ExchangeContract } from '@0x/contracts-exchange';
import { artifacts as exchangeArtifacts, ExchangeContract } from '@0x/contracts-exchange'; import { blockchainTests, constants, expect, orderHashUtils, OrderStatus } from '@0x/contracts-test-utils';
import { import { assetDataUtils } from '@0x/order-utils';
chaiSetup,
constants,
orderHashUtils,
OrderFactory,
OrderStatus,
provider,
txDefaults,
web3Wrapper,
} from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { OrderTransferResults, SignedOrder } from '@0x/types'; import { OrderTransferResults, SignedOrder } from '@0x/types';
import { BigNumber, providerUtils } from '@0x/utils'; import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
import { artifacts, DevUtilsContract } from '@0x/contracts-dev-utils'; import { Maker } from '../framework/actors/maker';
import { DeploymentManager } from '../framework/deployment_manager';
chaiSetup.configure(); // TODO(jalextowle): This can be cleaned up by using the actors more.
const expect = chai.expect; blockchainTests.resets.only('OrderValidationUtils/OrderTransferSimulatorUtils', env => {
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
let makerAddress: string;
let takerAddress: string; let takerAddress: string;
let owner: string; let owner: string;
let erc20AssetData: string;
let erc20AssetData2: string;
let erc721AssetData: string;
let feeAssetData: string;
let maker: Maker;
let devUtils: DevUtilsContract;
let erc20Token: DummyERC20TokenContract; let erc20Token: DummyERC20TokenContract;
let erc20Token2: DummyERC20TokenContract; let erc20Token2: DummyERC20TokenContract;
let feeErc20Token: DummyERC20TokenContract; let feeErc20Token: DummyERC20TokenContract;
let erc721Token: DummyERC721TokenContract;
let exchange: ExchangeContract;
let devUtils: DevUtilsContract;
let erc20Proxy: ERC20ProxyContract; let erc20Proxy: ERC20ProxyContract;
let erc721Proxy: ERC721ProxyContract; let exchange: ExchangeContract;
let multiAssetProxy: MultiAssetProxyContract;
let erc20AssetData: string;
let erc20AssetData2: string;
let feeAssetData: string;
let erc721AssetData: string;
let signedOrder: SignedOrder; let signedOrder: SignedOrder;
let orderFactory: OrderFactory;
const tokenId = new BigNumber(123456789);
before(async () => { before(async () => {
await blockchainLifecycle.startAsync(); [takerAddress, owner] = await env.getAccountAddressesAsync();
});
after(async () => { const deployment = await DeploymentManager.deployAsync(env, {
await blockchainLifecycle.revertAsync(); numErc20TokensToDeploy: 3,
numErc721TokensToDeploy: 1,
owner,
}); });
erc20Token = deployment.tokens.erc20[0];
erc20Token2 = deployment.tokens.erc20[1];
feeErc20Token = deployment.tokens.erc20[2];
erc20Proxy = deployment.assetProxies.erc20Proxy;
devUtils = deployment.devUtils;
exchange = deployment.exchange;
before(async () => { erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20Token.address);
const accounts = await web3Wrapper.getAvailableAddressesAsync(); erc20AssetData2 = assetDataUtils.encodeERC20AssetData(erc20Token2.address);
const usedAddresses = ([owner, makerAddress, takerAddress] = accounts.slice(0, 3)); feeAssetData = assetDataUtils.encodeERC20AssetData(feeErc20Token.address);
const chainId = await providerUtils.getChainIdAsync(provider);
const erc20Wrapper = new ERC20Wrapper(provider, usedAddresses, owner); maker = new Maker({
const erc721Wrapper = new ERC721Wrapper(provider, usedAddresses, owner); name: 'Maker',
deployment,
const numDummyErc20ToDeploy = 3; orderConfig: {
[erc20Token, erc20Token2, feeErc20Token] = await erc20Wrapper.deployDummyTokensAsync(
numDummyErc20ToDeploy,
constants.DUMMY_TOKEN_DECIMALS,
);
erc20Proxy = await erc20Wrapper.deployProxyAsync();
[erc721Token] = await erc721Wrapper.deployDummyTokensAsync();
erc721Proxy = await erc721Wrapper.deployProxyAsync();
exchange = await ExchangeContract.deployFrom0xArtifactAsync(
exchangeArtifacts.Exchange,
provider,
txDefaults,
{},
new BigNumber(chainId),
);
multiAssetProxy = await MultiAssetProxyContract.deployFrom0xArtifactAsync(
proxyArtifacts.MultiAssetProxy,
provider,
txDefaults,
artifacts,
);
await exchange.registerAssetProxy(erc20Proxy.address).awaitTransactionSuccessAsync({ from: owner });
await exchange.registerAssetProxy(erc721Proxy.address).awaitTransactionSuccessAsync({ from: owner });
await exchange.registerAssetProxy(multiAssetProxy.address).awaitTransactionSuccessAsync({ from: owner });
await erc20Proxy.addAuthorizedAddress(exchange.address).awaitTransactionSuccessAsync({ from: owner });
await erc721Proxy.addAuthorizedAddress(exchange.address).awaitTransactionSuccessAsync({ from: owner });
devUtils = await DevUtilsContract.deployFrom0xArtifactAsync(
artifacts.DevUtils,
provider,
txDefaults,
artifacts,
exchange.address,
);
feeAssetData = await devUtils.encodeERC20AssetData(feeErc20Token.address).callAsync();
erc20AssetData = await devUtils.encodeERC20AssetData(erc20Token.address).callAsync();
erc20AssetData2 = await devUtils.encodeERC20AssetData(erc20Token2.address).callAsync();
erc721AssetData = await devUtils.encodeERC721AssetData(erc721Token.address, tokenId).callAsync();
const defaultOrderParams = {
...constants.STATIC_ORDER_PARAMS,
makerAddress,
feeRecipientAddress: constants.NULL_ADDRESS,
makerAssetData: erc20AssetData, makerAssetData: erc20AssetData,
takerAssetData: erc20AssetData2, takerAssetData: erc20AssetData2,
makerFeeAssetData: feeAssetData, makerFeeAssetData: feeAssetData,
takerFeeAssetData: feeAssetData, takerFeeAssetData: feeAssetData,
exchangeAddress: exchange.address, feeRecipientAddress: constants.NULL_ADDRESS,
chainId, },
};
const privateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)];
orderFactory = new OrderFactory(privateKey, defaultOrderParams);
}); });
/*
beforeEach(async () => { await Promise.all(deployment.tokens.erc20.map(async token => maker.configureERC20TokenAsync(token)));
await blockchainLifecycle.startAsync(); */
}); const [tokenID] = await maker.configureERC721TokenAsync(deployment.tokens.erc721[0]);
afterEach(async () => { erc721AssetData = assetDataUtils.encodeERC721AssetData(deployment.tokens.erc721[0].address, tokenID);
await blockchainLifecycle.revertAsync();
}); });
describe('getTransferableAssetAmount', () => { describe('getTransferableAssetAmount', () => {
it('should return the balance when balance < allowance', async () => { it('should return the balance when balance < allowance', async () => {
const balance = new BigNumber(123); const balance = new BigNumber(123);
const allowance = new BigNumber(456); const allowance = new BigNumber(456);
await erc20Token.setBalance(makerAddress, balance).awaitTransactionSuccessAsync(); await erc20Token.setBalance(maker.address, balance).awaitTransactionSuccessAsync();
await erc20Token.approve(erc20Proxy.address, allowance).awaitTransactionSuccessAsync({ await erc20Token.approve(erc20Proxy.address, allowance).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
const transferableAmount = await devUtils const transferableAmount = await devUtils
.getTransferableAssetAmount(makerAddress, erc20AssetData) .getTransferableAssetAmount(maker.address, erc20AssetData)
.callAsync(); .callAsync();
expect(transferableAmount).to.bignumber.equal(balance); expect(transferableAmount).to.bignumber.equal(balance);
}); });
it('should return the allowance when allowance < balance', async () => { it('should return the allowance when allowance < balance', async () => {
const balance = new BigNumber(456); const balance = new BigNumber(456);
const allowance = new BigNumber(123); const allowance = new BigNumber(123);
await erc20Token.setBalance(makerAddress, balance).awaitTransactionSuccessAsync(); await erc20Token.setBalance(maker.address, balance).awaitTransactionSuccessAsync();
await erc20Token.approve(erc20Proxy.address, allowance).awaitTransactionSuccessAsync({ await erc20Token.approve(erc20Proxy.address, allowance).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
const transferableAmount = await devUtils const transferableAmount = await devUtils
.getTransferableAssetAmount(makerAddress, erc20AssetData) .getTransferableAssetAmount(maker.address, erc20AssetData)
.callAsync(); .callAsync();
expect(transferableAmount).to.bignumber.equal(allowance); expect(transferableAmount).to.bignumber.equal(allowance);
}); });
@ -165,23 +98,23 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
.callAsync(); .callAsync();
const transferableAmount1 = new BigNumber(10); const transferableAmount1 = new BigNumber(10);
const transferableAmount2 = new BigNumber(5); const transferableAmount2 = new BigNumber(5);
await erc20Token.setBalance(makerAddress, transferableAmount1).awaitTransactionSuccessAsync(); await erc20Token.setBalance(maker.address, transferableAmount1).awaitTransactionSuccessAsync();
await erc20Token.approve(erc20Proxy.address, transferableAmount1).awaitTransactionSuccessAsync({ await erc20Token.approve(erc20Proxy.address, transferableAmount1).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
await erc20Token2.setBalance(makerAddress, transferableAmount2).awaitTransactionSuccessAsync(); await erc20Token2.setBalance(maker.address, transferableAmount2).awaitTransactionSuccessAsync();
await erc20Token2.approve(erc20Proxy.address, transferableAmount2).awaitTransactionSuccessAsync({ await erc20Token2.approve(erc20Proxy.address, transferableAmount2).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
const transferableAmount = await devUtils const transferableAmount = await devUtils
.getTransferableAssetAmount(makerAddress, multiAssetData) .getTransferableAssetAmount(maker.address, multiAssetData)
.callAsync(); .callAsync();
expect(transferableAmount).to.bignumber.equal(transferableAmount2); expect(transferableAmount).to.bignumber.equal(transferableAmount2);
}); });
}); });
describe('getOrderRelevantState', () => { describe('getOrderRelevantState', () => {
beforeEach(async () => { beforeEach(async () => {
signedOrder = await orderFactory.newSignedOrderAsync(); signedOrder = await maker.signOrderAsync({});
}); });
it('should return the correct orderInfo when the order is valid', async () => { it('should return the correct orderInfo when the order is valid', async () => {
const [orderInfo] = await devUtils.getOrderRelevantState(signedOrder, signedOrder.signature).callAsync(); const [orderInfo] = await devUtils.getOrderRelevantState(signedOrder, signedOrder.signature).callAsync();
@ -209,9 +142,9 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
expect(fillableTakerAssetAmount).to.bignumber.equal(constants.ZERO_AMOUNT); expect(fillableTakerAssetAmount).to.bignumber.equal(constants.ZERO_AMOUNT);
}); });
it('should return a fillableTakerAssetAmount of 0 when fee balances/allowances are insufficient', async () => { it('should return a fillableTakerAssetAmount of 0 when fee balances/allowances are insufficient', async () => {
await erc20Token.setBalance(makerAddress, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync(); await erc20Token.setBalance(maker.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync();
await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
const [, fillableTakerAssetAmount] = await devUtils const [, fillableTakerAssetAmount] = await devUtils
.getOrderRelevantState(signedOrder, signedOrder.signature) .getOrderRelevantState(signedOrder, signedOrder.signature)
@ -222,27 +155,37 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
const multiAssetData = await devUtils const multiAssetData = await devUtils
.encodeMultiAssetData([new BigNumber(1), new BigNumber(1)], [erc20AssetData, erc20AssetData2]) .encodeMultiAssetData([new BigNumber(1), new BigNumber(1)], [erc20AssetData, erc20AssetData2])
.callAsync(); .callAsync();
signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetData: multiAssetData }); signedOrder = await maker.signOrderAsync({ makerAssetData: multiAssetData });
await erc20Token.setBalance(makerAddress, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync(); await erc20Token.setBalance(maker.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync();
await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
const [, fillableTakerAssetAmount] = await devUtils const [, fillableTakerAssetAmount] = await devUtils
.getOrderRelevantState(signedOrder, signedOrder.signature) .getOrderRelevantState(signedOrder, signedOrder.signature)
.callAsync(); .callAsync();
expect(fillableTakerAssetAmount).to.bignumber.equal(constants.ZERO_AMOUNT); expect(fillableTakerAssetAmount).to.bignumber.equal(constants.ZERO_AMOUNT);
}); });
it('should return a fillableTakerAssetAmount of 0 when an erc721 asset is duplicated in a multi-asset proxy order', async () => {
const multiAssetData = await devUtils
.encodeMultiAssetData([new BigNumber(1), new BigNumber(1)], [erc721AssetData, erc721AssetData])
.callAsync();
signedOrder = await maker.signOrderAsync({ makerAssetData: multiAssetData });
const [, fillableTakerAssetAmount] = await devUtils
.getOrderRelevantState(signedOrder, signedOrder.signature)
.callAsync();
expect(fillableTakerAssetAmount).to.bignumber.equal(constants.ZERO_AMOUNT);
});
it('should return the correct fillableTakerAssetAmount when fee balances/allowances are partially sufficient', async () => { it('should return the correct fillableTakerAssetAmount when fee balances/allowances are partially sufficient', async () => {
await erc20Token.setBalance(makerAddress, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync(); await erc20Token.setBalance(maker.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync();
await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
const divisor = 4; const divisor = 4;
await feeErc20Token await feeErc20Token
.setBalance(makerAddress, signedOrder.makerFee.dividedToIntegerBy(divisor)) .setBalance(maker.address, signedOrder.makerFee.dividedToIntegerBy(divisor))
.awaitTransactionSuccessAsync(); .awaitTransactionSuccessAsync();
await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({ await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
const [, fillableTakerAssetAmount] = await devUtils const [, fillableTakerAssetAmount] = await devUtils
.getOrderRelevantState(signedOrder, signedOrder.signature) .getOrderRelevantState(signedOrder, signedOrder.signature)
@ -254,14 +197,14 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
it('should return the correct fillableTakerAssetAmount when non-fee balances/allowances are partially sufficient', async () => { it('should return the correct fillableTakerAssetAmount when non-fee balances/allowances are partially sufficient', async () => {
const divisor = 4; const divisor = 4;
await erc20Token await erc20Token
.setBalance(makerAddress, signedOrder.makerAssetAmount.dividedToIntegerBy(divisor)) .setBalance(maker.address, signedOrder.makerAssetAmount.dividedToIntegerBy(divisor))
.awaitTransactionSuccessAsync(); .awaitTransactionSuccessAsync();
await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
await feeErc20Token.setBalance(makerAddress, signedOrder.makerFee).awaitTransactionSuccessAsync(); await feeErc20Token.setBalance(maker.address, signedOrder.makerFee).awaitTransactionSuccessAsync();
await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({ await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
const [, fillableTakerAssetAmount] = await devUtils const [, fillableTakerAssetAmount] = await devUtils
.getOrderRelevantState(signedOrder, signedOrder.signature) .getOrderRelevantState(signedOrder, signedOrder.signature)
@ -274,23 +217,23 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
const multiAssetData = await devUtils const multiAssetData = await devUtils
.encodeMultiAssetData([new BigNumber(1), new BigNumber(1)], [erc20AssetData, erc20AssetData2]) .encodeMultiAssetData([new BigNumber(1), new BigNumber(1)], [erc20AssetData, erc20AssetData2])
.callAsync(); .callAsync();
signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetData: multiAssetData }); signedOrder = await maker.signOrderAsync({ makerAssetData: multiAssetData });
await erc20Token.setBalance(makerAddress, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync(); await erc20Token.setBalance(maker.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync();
await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
await feeErc20Token.setBalance(makerAddress, signedOrder.makerFee).awaitTransactionSuccessAsync(); await feeErc20Token.setBalance(maker.address, signedOrder.makerFee).awaitTransactionSuccessAsync();
await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({ await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
const divisor = 4; const divisor = 4;
await erc20Token2 await erc20Token2
.setBalance(makerAddress, signedOrder.makerAssetAmount.dividedToIntegerBy(divisor)) .setBalance(maker.address, signedOrder.makerAssetAmount.dividedToIntegerBy(divisor))
.awaitTransactionSuccessAsync(); .awaitTransactionSuccessAsync();
await erc20Token2 await erc20Token2
.approve(erc20Proxy.address, signedOrder.makerAssetAmount.dividedToIntegerBy(divisor)) .approve(erc20Proxy.address, signedOrder.makerAssetAmount.dividedToIntegerBy(divisor))
.awaitTransactionSuccessAsync({ .awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
const [, fillableTakerAssetAmount] = await devUtils const [, fillableTakerAssetAmount] = await devUtils
.getOrderRelevantState(signedOrder, signedOrder.signature) .getOrderRelevantState(signedOrder, signedOrder.signature)
@ -300,9 +243,9 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
); );
}); });
it('should return a fillableTakerAssetAmount of 0 when non-fee balances/allowances are insufficient', async () => { it('should return a fillableTakerAssetAmount of 0 when non-fee balances/allowances are insufficient', async () => {
await feeErc20Token.setBalance(makerAddress, signedOrder.makerFee).awaitTransactionSuccessAsync(); await feeErc20Token.setBalance(maker.address, signedOrder.makerFee).awaitTransactionSuccessAsync();
await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({ await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
const [, fillableTakerAssetAmount] = await devUtils const [, fillableTakerAssetAmount] = await devUtils
.getOrderRelevantState(signedOrder, signedOrder.signature) .getOrderRelevantState(signedOrder, signedOrder.signature)
@ -310,13 +253,13 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
expect(fillableTakerAssetAmount).to.bignumber.equal(constants.ZERO_AMOUNT); expect(fillableTakerAssetAmount).to.bignumber.equal(constants.ZERO_AMOUNT);
}); });
it('should return a fillableTakerAssetAmount equal to the takerAssetAmount when the order is unfilled and balances/allowances are sufficient', async () => { it('should return a fillableTakerAssetAmount equal to the takerAssetAmount when the order is unfilled and balances/allowances are sufficient', async () => {
await erc20Token.setBalance(makerAddress, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync(); await erc20Token.setBalance(maker.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync();
await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
await feeErc20Token.setBalance(makerAddress, signedOrder.makerFee).awaitTransactionSuccessAsync(); await feeErc20Token.setBalance(maker.address, signedOrder.makerFee).awaitTransactionSuccessAsync();
await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({ await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
const [, fillableTakerAssetAmount] = await devUtils const [, fillableTakerAssetAmount] = await devUtils
.getOrderRelevantState(signedOrder, signedOrder.signature) .getOrderRelevantState(signedOrder, signedOrder.signature)
@ -324,16 +267,16 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
expect(fillableTakerAssetAmount).to.bignumber.equal(signedOrder.takerAssetAmount); expect(fillableTakerAssetAmount).to.bignumber.equal(signedOrder.takerAssetAmount);
}); });
it('should return the correct fillableTakerAssetAmount when balances/allowances are partially sufficient and makerAsset=makerFeeAsset', async () => { it('should return the correct fillableTakerAssetAmount when balances/allowances are partially sufficient and makerAsset=makerFeeAsset', async () => {
signedOrder = await orderFactory.newSignedOrderAsync({ signedOrder = await maker.signOrderAsync({
makerAssetData: feeAssetData, makerAssetData: feeAssetData,
makerAssetAmount: new BigNumber(10), makerAssetAmount: new BigNumber(10),
takerAssetAmount: new BigNumber(20), takerAssetAmount: new BigNumber(20),
makerFee: new BigNumber(40), makerFee: new BigNumber(40),
}); });
const transferableMakerAssetAmount = new BigNumber(10); const transferableMakerAssetAmount = new BigNumber(10);
await feeErc20Token.setBalance(makerAddress, transferableMakerAssetAmount).awaitTransactionSuccessAsync(); await feeErc20Token.setBalance(maker.address, transferableMakerAssetAmount).awaitTransactionSuccessAsync();
await feeErc20Token.approve(erc20Proxy.address, transferableMakerAssetAmount).awaitTransactionSuccessAsync({ await feeErc20Token.approve(erc20Proxy.address, transferableMakerAssetAmount).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
const expectedFillableTakerAssetAmount = transferableMakerAssetAmount const expectedFillableTakerAssetAmount = transferableMakerAssetAmount
.times(signedOrder.takerAssetAmount) .times(signedOrder.takerAssetAmount)
@ -344,10 +287,10 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
expect(fillableTakerAssetAmount).to.bignumber.equal(expectedFillableTakerAssetAmount); expect(fillableTakerAssetAmount).to.bignumber.equal(expectedFillableTakerAssetAmount);
}); });
it('should return the correct fillabeTakerassetAmount when makerAsset balances/allowances are sufficient and there are no maker fees', async () => { it('should return the correct fillabeTakerassetAmount when makerAsset balances/allowances are sufficient and there are no maker fees', async () => {
signedOrder = await orderFactory.newSignedOrderAsync({ makerFee: constants.ZERO_AMOUNT }); signedOrder = await maker.signOrderAsync({ makerFee: constants.ZERO_AMOUNT });
await erc20Token.setBalance(makerAddress, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync(); await erc20Token.setBalance(maker.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync();
await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
const [, fillableTakerAssetAmount] = await devUtils const [, fillableTakerAssetAmount] = await devUtils
.getOrderRelevantState(signedOrder, signedOrder.signature) .getOrderRelevantState(signedOrder, signedOrder.signature)
@ -355,13 +298,13 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
expect(fillableTakerAssetAmount).to.bignumber.equal(signedOrder.takerAssetAmount); expect(fillableTakerAssetAmount).to.bignumber.equal(signedOrder.takerAssetAmount);
}); });
it('should return a fillableTakerAssetAmount when the remaining takerAssetAmount is less than the transferable amount', async () => { it('should return a fillableTakerAssetAmount when the remaining takerAssetAmount is less than the transferable amount', async () => {
await erc20Token.setBalance(makerAddress, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync(); await erc20Token.setBalance(maker.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync();
await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
await feeErc20Token.setBalance(makerAddress, signedOrder.makerFee).awaitTransactionSuccessAsync(); await feeErc20Token.setBalance(maker.address, signedOrder.makerFee).awaitTransactionSuccessAsync();
await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({ await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
await erc20Token2.setBalance(takerAddress, signedOrder.takerAssetAmount).awaitTransactionSuccessAsync(); await erc20Token2.setBalance(takerAddress, signedOrder.takerAssetAmount).awaitTransactionSuccessAsync();
await erc20Token2.approve(erc20Proxy.address, signedOrder.takerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token2.approve(erc20Proxy.address, signedOrder.takerAssetAmount).awaitTransactionSuccessAsync({
@ -375,7 +318,7 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
const takerAssetFillAmount = signedOrder.takerAssetAmount.dividedToIntegerBy(4); const takerAssetFillAmount = signedOrder.takerAssetAmount.dividedToIntegerBy(4);
await exchange await exchange
.fillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature) .fillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature)
.awaitTransactionSuccessAsync({ from: takerAddress }); .awaitTransactionSuccessAsync({ from: takerAddress, value: DeploymentManager.protocolFee });
const [, fillableTakerAssetAmount] = await devUtils const [, fillableTakerAssetAmount] = await devUtils
.getOrderRelevantState(signedOrder, signedOrder.signature) .getOrderRelevantState(signedOrder, signedOrder.signature)
.callAsync(); .callAsync();
@ -384,15 +327,15 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
); );
}); });
it('should return correct info even when there are no fees specified', async () => { it('should return correct info even when there are no fees specified', async () => {
signedOrder = await orderFactory.newSignedOrderAsync({ signedOrder = await maker.signOrderAsync({
makerFee: new BigNumber(0), makerFee: new BigNumber(0),
takerFee: new BigNumber(0), takerFee: new BigNumber(0),
makerFeeAssetData: '0x', makerFeeAssetData: '0x',
takerFeeAssetData: '0x', takerFeeAssetData: '0x',
}); });
await erc20Token.setBalance(makerAddress, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync(); await erc20Token.setBalance(maker.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync();
await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
const [orderInfo, fillableTakerAssetAmount, isValidSignature] = await devUtils const [orderInfo, fillableTakerAssetAmount, isValidSignature] = await devUtils
.getOrderRelevantState(signedOrder, signedOrder.signature) .getOrderRelevantState(signedOrder, signedOrder.signature)
@ -406,18 +349,21 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
}); });
describe('getOrderRelevantStates', async () => { describe('getOrderRelevantStates', async () => {
it('should return the correct information for multiple orders', async () => { it('should return the correct information for multiple orders', async () => {
signedOrder = await orderFactory.newSignedOrderAsync(); signedOrder = await maker.signOrderAsync();
await erc20Token.setBalance(makerAddress, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync(); await erc20Token.setBalance(maker.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync();
await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
await feeErc20Token.setBalance(makerAddress, signedOrder.makerFee).awaitTransactionSuccessAsync(); await feeErc20Token.setBalance(maker.address, signedOrder.makerFee).awaitTransactionSuccessAsync();
await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({ await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
});
const signedOrder2 = await maker.signOrderAsync({
makerAssetData: erc721AssetData,
makerAssetAmount: new BigNumber(1),
}); });
const signedOrder2 = await orderFactory.newSignedOrderAsync({ makerAssetData: erc721AssetData });
const invalidSignature = '0x01'; const invalidSignature = '0x01';
await exchange.cancelOrder(signedOrder2).awaitTransactionSuccessAsync({ from: makerAddress }); await exchange.cancelOrder(signedOrder2).awaitTransactionSuccessAsync({ from: maker.address });
const [ordersInfo, fillableTakerAssetAmounts, isValidSignature] = await devUtils const [ordersInfo, fillableTakerAssetAmounts, isValidSignature] = await devUtils
.getOrderRelevantStates([signedOrder, signedOrder2], [signedOrder.signature, invalidSignature]) .getOrderRelevantStates([signedOrder, signedOrder2], [signedOrder.signature, invalidSignature])
.callAsync(); .callAsync();
@ -435,7 +381,7 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
}); });
describe('getSimulatedOrderTransferResults', () => { describe('getSimulatedOrderTransferResults', () => {
beforeEach(async () => { beforeEach(async () => {
signedOrder = await orderFactory.newSignedOrderAsync(); signedOrder = await maker.signOrderAsync();
}); });
it('should return TakerAssetDataFailed if the takerAsset transfer fails', async () => { it('should return TakerAssetDataFailed if the takerAsset transfer fails', async () => {
const orderTransferResults = await devUtils const orderTransferResults = await devUtils
@ -462,11 +408,11 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
await erc20Token2.approve(erc20Proxy.address, signedOrder.takerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token2.approve(erc20Proxy.address, signedOrder.takerAssetAmount).awaitTransactionSuccessAsync({
from: takerAddress, from: takerAddress,
}); });
await erc20Token.setBalance(makerAddress, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.setBalance(maker.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: owner, from: owner,
}); });
await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
const orderTransferResults = await devUtils const orderTransferResults = await devUtils
.getSimulatedOrderTransferResults(signedOrder, takerAddress, signedOrder.takerAssetAmount) .getSimulatedOrderTransferResults(signedOrder, takerAddress, signedOrder.takerAssetAmount)
@ -480,11 +426,11 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
await erc20Token2.approve(erc20Proxy.address, signedOrder.takerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token2.approve(erc20Proxy.address, signedOrder.takerAssetAmount).awaitTransactionSuccessAsync({
from: takerAddress, from: takerAddress,
}); });
await erc20Token.setBalance(makerAddress, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.setBalance(maker.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: owner, from: owner,
}); });
await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
await feeErc20Token.setBalance(takerAddress, signedOrder.takerFee).awaitTransactionSuccessAsync({ await feeErc20Token.setBalance(takerAddress, signedOrder.takerFee).awaitTransactionSuccessAsync({
from: owner, from: owner,
@ -504,11 +450,11 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
await erc20Token2.approve(erc20Proxy.address, signedOrder.takerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token2.approve(erc20Proxy.address, signedOrder.takerAssetAmount).awaitTransactionSuccessAsync({
from: takerAddress, from: takerAddress,
}); });
await erc20Token.setBalance(makerAddress, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.setBalance(maker.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: owner, from: owner,
}); });
await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
await feeErc20Token.setBalance(takerAddress, signedOrder.takerFee).awaitTransactionSuccessAsync({ await feeErc20Token.setBalance(takerAddress, signedOrder.takerFee).awaitTransactionSuccessAsync({
from: owner, from: owner,
@ -516,11 +462,11 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
await feeErc20Token.approve(erc20Proxy.address, signedOrder.takerFee).awaitTransactionSuccessAsync({ await feeErc20Token.approve(erc20Proxy.address, signedOrder.takerFee).awaitTransactionSuccessAsync({
from: takerAddress, from: takerAddress,
}); });
await feeErc20Token.setBalance(makerAddress, signedOrder.makerFee).awaitTransactionSuccessAsync({ await feeErc20Token.setBalance(maker.address, signedOrder.makerFee).awaitTransactionSuccessAsync({
from: owner, from: owner,
}); });
await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({ await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
const orderTransferResults = await devUtils const orderTransferResults = await devUtils
.getSimulatedOrderTransferResults(signedOrder, takerAddress, signedOrder.takerAssetAmount) .getSimulatedOrderTransferResults(signedOrder, takerAddress, signedOrder.takerAssetAmount)
@ -536,11 +482,11 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
await erc20Token2.approve(erc20Proxy.address, signedOrder.takerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token2.approve(erc20Proxy.address, signedOrder.takerAssetAmount).awaitTransactionSuccessAsync({
from: takerAddress, from: takerAddress,
}); });
await erc20Token.setBalance(makerAddress, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.setBalance(maker.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: owner, from: owner,
}); });
await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
await feeErc20Token.setBalance(takerAddress, signedOrder.takerFee).awaitTransactionSuccessAsync({ await feeErc20Token.setBalance(takerAddress, signedOrder.takerFee).awaitTransactionSuccessAsync({
from: owner, from: owner,
@ -548,11 +494,11 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
await feeErc20Token.approve(erc20Proxy.address, signedOrder.takerFee).awaitTransactionSuccessAsync({ await feeErc20Token.approve(erc20Proxy.address, signedOrder.takerFee).awaitTransactionSuccessAsync({
from: takerAddress, from: takerAddress,
}); });
await feeErc20Token.setBalance(makerAddress, signedOrder.makerFee).awaitTransactionSuccessAsync({ await feeErc20Token.setBalance(maker.address, signedOrder.makerFee).awaitTransactionSuccessAsync({
from: owner, from: owner,
}); });
await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({ await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
const orderTransferResults = await devUtils const orderTransferResults = await devUtils
.getSimulatedOrderTransferResults(signedOrder, takerAddress, signedOrder.takerAssetAmount.dividedBy(2)) .getSimulatedOrderTransferResults(signedOrder, takerAddress, signedOrder.takerAssetAmount.dividedBy(2))
@ -569,11 +515,11 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
await erc20Token2.approve(erc20Proxy.address, signedOrder.takerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token2.approve(erc20Proxy.address, signedOrder.takerAssetAmount).awaitTransactionSuccessAsync({
from: takerAddress, from: takerAddress,
}); });
await erc20Token.setBalance(makerAddress, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.setBalance(maker.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: owner, from: owner,
}); });
await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({ await erc20Token.approve(erc20Proxy.address, signedOrder.makerAssetAmount).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
await feeErc20Token.setBalance(takerAddress, signedOrder.takerFee).awaitTransactionSuccessAsync({ await feeErc20Token.setBalance(takerAddress, signedOrder.takerFee).awaitTransactionSuccessAsync({
from: owner, from: owner,
@ -581,11 +527,11 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => {
await feeErc20Token.approve(erc20Proxy.address, signedOrder.takerFee).awaitTransactionSuccessAsync({ await feeErc20Token.approve(erc20Proxy.address, signedOrder.takerFee).awaitTransactionSuccessAsync({
from: takerAddress, from: takerAddress,
}); });
await feeErc20Token.setBalance(makerAddress, signedOrder.makerFee).awaitTransactionSuccessAsync({ await feeErc20Token.setBalance(maker.address, signedOrder.makerFee).awaitTransactionSuccessAsync({
from: owner, from: owner,
}); });
await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({ await feeErc20Token.approve(erc20Proxy.address, signedOrder.makerFee).awaitTransactionSuccessAsync({
from: makerAddress, from: maker.address,
}); });
const [orderTransferResults1, orderTransferResults2] = await devUtils const [orderTransferResults1, orderTransferResults2] = await devUtils
.getSimulatedOrdersTransferResults( .getSimulatedOrdersTransferResults(

View File

@ -8,7 +8,7 @@ import {
MultiAssetProxyContract, MultiAssetProxyContract,
StaticCallProxyContract, StaticCallProxyContract,
} from '@0x/contracts-asset-proxy'; } from '@0x/contracts-asset-proxy';
import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { artifacts as devUtilsArtifacts, DevUtilsContract } from '@0x/contracts-dev-utils';
import { artifacts as ERC1155Artifacts, ERC1155MintableContract } from '@0x/contracts-erc1155'; import { artifacts as ERC1155Artifacts, ERC1155MintableContract } from '@0x/contracts-erc1155';
import { artifacts as ERC20Artifacts, DummyERC20TokenContract, WETH9Contract } from '@0x/contracts-erc20'; import { artifacts as ERC20Artifacts, DummyERC20TokenContract, WETH9Contract } from '@0x/contracts-erc20';
import { artifacts as ERC721Artifacts, DummyERC721TokenContract } from '@0x/contracts-erc721'; import { artifacts as ERC721Artifacts, DummyERC721TokenContract } from '@0x/contracts-erc721';
@ -196,7 +196,13 @@ export class DeploymentManager {
staking.stakingProxy, staking.stakingProxy,
]); ]);
const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, environment.provider); const devUtils = await DevUtilsContract.deployFrom0xArtifactAsync(
devUtilsArtifacts.DevUtils,
environment.provider,
environment.txDefaults,
devUtilsArtifacts,
exchange.address,
);
const assetDataEncoder = new IAssetDataContract(constants.NULL_ADDRESS, environment.provider); const assetDataEncoder = new IAssetDataContract(constants.NULL_ADDRESS, environment.provider);
// Construct the new instance and return it. // Construct the new instance and return it.

View File

@ -1,11 +0,0 @@
[
{
"version": "0.0.1",
"changes": [
{
"note": "Created package",
"pr": 2261
}
]
}
]

View File

@ -1,75 +0,0 @@
## Tests
This package implements unit tests against 0x's smart contracts. Its primary purpose is to help avoid circular dependencies between the contract packages.
## Contributing
We strongly recommend that the community help us make improvements and determine the future direction of the protocol. To report bugs within this package, please create an issue in this repository.
For proposals regarding the 0x protocol's smart contract architecture, message format, or additional functionality, go to the [0x Improvement Proposals (ZEIPs)](https://github.com/0xProject/ZEIPs) repository and follow the contribution guidelines provided therein.
Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting started.
### Install Dependencies
If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them:
```bash
yarn config set workspaces-experimental true
```
Then install dependencies
```bash
yarn install
```
### Build
To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory:
```bash
PKG=@0x/contracts-tests yarn build
```
Or continuously rebuild on change:
```bash
PKG=@0x/contracts-tests yarn watch
```
If imports are rebuilt in their source packages, they do not need to be rebuilt here.
Example:
```
// contracts/tests/test/some-new/some_new_test.ts
import { SomeNewContract } from '@0x/contracts-some-new';
describe('should do its thing', () => {
const contractInstance = new SomeNewContract();
expect(contractInstance.someTruthyFunction.callAsync()).to.be.true();
})
```
Run `yarn watch` from `contracts/some-new`, and then running `yarn test` from this package should test the new changes.
### Clean
```bash
yarn clean
```
Since the purpose of this package is to test other packages, make sure you are running `yarn clean` as necessary in the imported packages as well.
### Lint
```bash
yarn lint
```
### Run Tests
```bash
yarn test
```

View File

@ -1,26 +0,0 @@
{
"artifactsDir": "./test/generated-artifacts",
"contractsDir": "./contracts",
"useDockerisedSolc": false,
"isOfflineMode": false,
"compilerSettings": {
"evmVersion": "constantinople",
"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"
]
}
}
}
}

View File

@ -1,88 +0,0 @@
{
"name": "@0x/contracts-tests",
"private": true,
"version": "0.0.8",
"engines": {
"node": ">=6.12"
},
"description": "Unit tests for 0x contracts",
"main": "lib/src/index.js",
"directories": {
"test": "test"
},
"scripts": {
"build": "tsc -b",
"build:ci": "yarn build",
"pre_build": "run-s compile contracts:gen generate_contract_wrappers contracts:copy",
"test": "yarn run_mocha",
"rebuild_and_test": "run-s build test",
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
"test:profiler": "SOLIDITY_PROFILER=true run-s build run_mocha profiler:report:html",
"test:trace": "SOLIDITY_REVERT_TRACE=true run-s build run_mocha",
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
"compile": "sol-compiler",
"watch": "sol-compiler -w",
"clean": "shx rm -rf lib test/generated-artifacts test/generated-wrappers generated-artifacts generated-wrappers",
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --output test/generated-wrappers --backend ethers",
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"coverage:report:text": "istanbul report text",
"coverage:report:html": "istanbul report html && open coverage/index.html",
"profiler:report:html": "istanbul report html && open coverage/index.html",
"coverage:report:lcov": "istanbul report lcov",
"test:circleci": "yarn test",
"contracts:gen": "contracts-gen generate",
"contracts:copy": "contracts-gen copy",
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol",
"compile:truffle": "truffle compile"
},
"config": {
"abis": "./generated-artifacts/@().json",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
},
"repository": {
"type": "git",
"url": "https://github.com/0xProject/0x-monorepo.git"
},
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/0xProject/0x-monorepo/issues"
},
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/tests/README.md",
"devDependencies": {
"@0x/abi-gen": "^5.0.2",
"@0x/base-contract": "^6.0.2",
"@0x/contracts-asset-proxy": "^3.0.2",
"@0x/contracts-dev-utils": "^1.0.2",
"@0x/contracts-erc1155": "^2.0.2",
"@0x/contracts-erc20": "^3.0.2",
"@0x/contracts-erc721": "^3.0.2",
"@0x/contracts-exchange": "^3.0.2",
"@0x/contracts-gen": "^2.0.2",
"@0x/contracts-test-utils": "^5.0.1",
"@0x/sol-compiler": "^4.0.2",
"@0x/tslint-config": "^4.0.0",
"@0x/types": "^3.1.1",
"@0x/typescript-typings": "^5.0.1",
"@0x/utils": "^5.1.1",
"@0x/web3-wrapper": "^7.0.2",
"@types/mocha": "^5.2.7",
"@types/node": "*",
"chai": "^4.0.1",
"chai-as-promised": "^7.1.0",
"chai-bignumber": "^3.0.0",
"dirty-chai": "^2.0.1",
"ethereum-types": "^3.0.0",
"make-promises-safe": "^1.1.0",
"mocha": "^6.2.0",
"npm-run-all": "^4.1.2",
"shx": "^0.2.2",
"solhint": "^1.4.1",
"truffle": "^5.0.32",
"tslint": "5.11.0",
"typescript": "3.0.1"
},
"publishConfig": {
"access": "private"
}
}

View File

@ -1,8 +0,0 @@
/*
* -----------------------------------------------------------------------------
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
* -----------------------------------------------------------------------------
*/
import { ContractArtifact } from 'ethereum-types';
export const artifacts = {};

View File

@ -1 +0,0 @@
export { artifacts } from './artifacts';

View File

@ -1,5 +0,0 @@
/*
* -----------------------------------------------------------------------------
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
* -----------------------------------------------------------------------------
*/

View File

@ -1,41 +0,0 @@
import { DevUtilsContract } from '@0x/contracts-dev-utils/lib/generated-wrappers/dev_utils';
import { Order } from '@0x/types';
import { BigNumber } from '@0x/utils';
import { chaiSetup } from '@0x/contracts-test-utils';
import { SupportedProvider } from 'ethereum-types';
import * as chai from 'chai';
chaiSetup.configure();
const expect = chai.expect;
const NULL_ADDRESS = '0x' + '00'.repeat(20);
describe('DevUtils.getOrderHash', () => {
it('should return the order hash', async () => {
const expectedOrderHash = '0x331cb7e07a757bae130702da6646c26531798c92bcfaf671817268fd2c188531';
const exchangeAddress = '0x1dc4c1cefef38a777b15aa20260a54e584b16c48';
const chainId = 50;
const order: Order = {
makerAddress: NULL_ADDRESS,
takerAddress: NULL_ADDRESS,
senderAddress: NULL_ADDRESS,
feeRecipientAddress: NULL_ADDRESS,
makerAssetData: NULL_ADDRESS,
takerAssetData: NULL_ADDRESS,
makerFeeAssetData: NULL_ADDRESS,
takerFeeAssetData: NULL_ADDRESS,
salt: new BigNumber(0),
makerFee: new BigNumber(0),
takerFee: new BigNumber(0),
makerAssetAmount: new BigNumber(0),
takerAssetAmount: new BigNumber(0),
expirationTimeSeconds: new BigNumber(0),
exchangeAddress,
chainId,
};
const devUtilsContract = new DevUtilsContract(NULL_ADDRESS, { isEIP1193: true } as SupportedProvider);
expect(
await devUtilsContract.getOrderHash(order, new BigNumber(chainId), exchangeAddress).callAsync(),
).to.be.equal(expectedOrderHash);
});
});

View File

@ -1,6 +0,0 @@
{
"extends": "../../tsconfig",
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
"exclude": ["./lib/**/*"]
}

View File

@ -51,7 +51,7 @@
"lint:contracts": "wsrun lint -p ${npm_package_config_contractsPackages} -c --fast-exit --stages --exclude-missing" "lint:contracts": "wsrun lint -p ${npm_package_config_contractsPackages} -c --fast-exit --stages --exclude-missing"
}, },
"config": { "config": {
"contractsPackages": "@0x/contracts-asset-proxy @0x/contracts-dev-utils @0x/contracts-erc20 @0x/contracts-erc20-bridge-sampler @0x/contracts-erc721 @0x/contracts-erc1155 @0x/contracts-exchange @0x/contracts-exchange-forwarder @0x/contracts-exchange-libs @0x/contracts-integrations @0x/contracts-multisig @0x/contracts-staking @0x/contracts-test-utils @0x/contracts-utils @0x/contracts-coordinator @0x/contracts-tests @0x/contracts-erc20-bridge-sampler", "contractsPackages": "@0x/contracts-asset-proxy @0x/contracts-dev-utils @0x/contracts-erc20 @0x/contracts-erc20-bridge-sampler @0x/contracts-erc721 @0x/contracts-erc1155 @0x/contracts-exchange @0x/contracts-exchange-forwarder @0x/contracts-exchange-libs @0x/contracts-integrations @0x/contracts-multisig @0x/contracts-staking @0x/contracts-test-utils @0x/contracts-utils @0x/contracts-coordinator @0x/contracts-erc20-bridge-sampler",
"mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic", "mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic",
"packagesWithDocPages": "0x.js @0x/contract-wrappers @0x/connect @0x/json-schemas @0x/subproviders @0x/web3-wrapper @0x/order-utils @0x/sol-compiler @0x/sol-coverage @0x/sol-profiler @0x/sol-trace @0x/dev-utils @0x/asset-swapper @0x/migrations @0x/orderbook @0x/contracts-asset-proxy @0x/contracts-coordinator @0x/contracts-dev-utils @0x/contracts-erc20 @0x/contracts-erc721 @0x/contracts-erc1155 @0x/contracts-exchange @0x/contracts-exchange-forwarder @0x/contracts-exchange-libs @0x/contracts-extensions @0x/contracts-staking", "packagesWithDocPages": "0x.js @0x/contract-wrappers @0x/connect @0x/json-schemas @0x/subproviders @0x/web3-wrapper @0x/order-utils @0x/sol-compiler @0x/sol-coverage @0x/sol-profiler @0x/sol-trace @0x/dev-utils @0x/asset-swapper @0x/migrations @0x/orderbook @0x/contracts-asset-proxy @0x/contracts-coordinator @0x/contracts-dev-utils @0x/contracts-erc20 @0x/contracts-erc721 @0x/contracts-erc1155 @0x/contracts-exchange @0x/contracts-exchange-forwarder @0x/contracts-exchange-libs @0x/contracts-extensions @0x/contracts-staking",
"ignoreDependencyVersions": "@types/styled-components @types/node", "ignoreDependencyVersions": "@types/styled-components @types/node",

View File

@ -1961,7 +1961,7 @@
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/bn.js@*", "@types/bn.js@^4.11.4": "@types/bn.js@*", "@types/bn.js@^4.11.3", "@types/bn.js@^4.11.4":
version "4.11.5" version "4.11.5"
resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.5.tgz#40e36197433f78f807524ec623afcf0169ac81dc" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.5.tgz#40e36197433f78f807524ec623afcf0169ac81dc"
dependencies: dependencies:
@ -3791,6 +3791,13 @@ bindings@^1.2.1, bindings@^1.3.0:
version "1.3.0" version "1.3.0"
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.0.tgz#b346f6ecf6a95f5a815c5839fc7cdb22502f1ed7" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.0.tgz#b346f6ecf6a95f5a815c5839fc7cdb22502f1ed7"
bindings@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df"
integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==
dependencies:
file-uri-to-path "1.0.0"
bip39@2.5.0, bip39@^2.5.0: bip39@2.5.0, bip39@^2.5.0:
version "2.5.0" version "2.5.0"
resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.5.0.tgz#51cbd5179460504a63ea3c000db3f787ca051235" resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.5.0.tgz#51cbd5179460504a63ea3c000db3f787ca051235"
@ -6772,6 +6779,19 @@ ethereumjs-util@^6.0.0, ethereumjs-util@^6.1.0, ethereumjs-util@~6.1.0:
safe-buffer "^5.1.1" safe-buffer "^5.1.1"
secp256k1 "^3.0.1" secp256k1 "^3.0.1"
ethereumjs-util@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.0.tgz#23ec79b2488a7d041242f01e25f24e5ad0357960"
integrity sha512-vb0XN9J2QGdZGIEKG2vXM+kUdEivUfU6Wmi5y0cg+LRhDYKnXIZ/Lz7XjFbHRR9VIKq2lVGLzGBkA++y2nOdOQ==
dependencies:
"@types/bn.js" "^4.11.3"
bn.js "^4.11.0"
create-hash "^1.1.2"
ethjs-util "0.1.6"
keccak "^2.0.0"
rlp "^2.2.3"
secp256k1 "^3.0.1"
ethereumjs-vm@2.6.0: ethereumjs-vm@2.6.0:
version "2.6.0" version "2.6.0"
resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz#76243ed8de031b408793ac33907fb3407fe400c6" resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz#76243ed8de031b408793ac33907fb3407fe400c6"
@ -7362,6 +7382,11 @@ file-type@^6.1.0:
version "6.2.0" version "6.2.0"
resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919"
file-uri-to-path@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
filename-regex@^2.0.0: filename-regex@^2.0.0:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26"
@ -8807,6 +8832,11 @@ inherits@2.0.1:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
inherits@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
ini@1.x.x, ini@^1.3.2, ini@^1.3.4, ini@~1.3.0: ini@1.x.x, ini@^1.3.2, ini@^1.3.4, ini@~1.3.0:
version "1.3.5" version "1.3.5"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
@ -10403,6 +10433,16 @@ keccak@^1.0.2:
nan "^2.2.1" nan "^2.2.1"
safe-buffer "^5.1.0" safe-buffer "^5.1.0"
keccak@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/keccak/-/keccak-2.1.0.tgz#734ea53f2edcfd0f42cdb8d5f4c358fef052752b"
integrity sha512-m1wbJRTo+gWbctZWay9i26v5fFnYkOn7D5PCxJ3fZUGUEb49dE1Pm4BREUYCt/aoO6di7jeoGmhvqN9Nzylm3Q==
dependencies:
bindings "^1.5.0"
inherits "^2.0.4"
nan "^2.14.0"
safe-buffer "^5.2.0"
keccakjs@^0.2.0, keccakjs@^0.2.1: keccakjs@^0.2.0, keccakjs@^0.2.1:
version "0.2.1" version "0.2.1"
resolved "https://registry.yarnpkg.com/keccakjs/-/keccakjs-0.2.1.tgz#1d633af907ef305bbf9f2fa616d56c44561dfa4d" resolved "https://registry.yarnpkg.com/keccakjs/-/keccakjs-0.2.1.tgz#1d633af907ef305bbf9f2fa616d56c44561dfa4d"
@ -11703,7 +11743,7 @@ nan@^2.11.0:
version "2.12.1" version "2.12.1"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552"
nan@^2.12.1: nan@^2.12.1, nan@^2.14.0:
version "2.14.0" version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
@ -14278,6 +14318,13 @@ rlp@^2.2.1, rlp@^2.2.2:
bn.js "^4.11.1" bn.js "^4.11.1"
safe-buffer "^5.1.1" safe-buffer "^5.1.1"
rlp@^2.2.3:
version "2.2.4"
resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.4.tgz#d6b0e1659e9285fc509a5d169a9bd06f704951c1"
integrity sha512-fdq2yYCWpAQBhwkZv+Z8o/Z4sPmYm1CUq6P7n6lVTOdb949CnqA0sndXal5C1NleSVSZm6q5F3iEbauyVln/iw==
dependencies:
bn.js "^4.11.1"
rollbar-sourcemap-webpack-plugin@^2.4.0: rollbar-sourcemap-webpack-plugin@^2.4.0:
version "2.4.0" version "2.4.0"
resolved "https://registry.yarnpkg.com/rollbar-sourcemap-webpack-plugin/-/rollbar-sourcemap-webpack-plugin-2.4.0.tgz#0d864fe4d7a141a09fafd417415b704f95faddad" resolved "https://registry.yarnpkg.com/rollbar-sourcemap-webpack-plugin/-/rollbar-sourcemap-webpack-plugin-2.4.0.tgz#0d864fe4d7a141a09fafd417415b704f95faddad"