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