merge development
This commit is contained in:
commit
843caf86fb
@ -2,10 +2,6 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Set evmVersion to byzantium",
|
||||
"pr": 1678
|
||||
},
|
||||
{
|
||||
"note": "Do not reexport external dependencies",
|
||||
"pr": 1682
|
||||
@ -17,6 +13,10 @@
|
||||
{
|
||||
"note": "Bumped solidity version to ^0.5.5",
|
||||
"pr": 1701
|
||||
},
|
||||
{
|
||||
"note": "Integration testing for ERC1155Proxy",
|
||||
"pr": 1673
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -4,7 +4,7 @@
|
||||
"useDockerisedSolc": true,
|
||||
"isOfflineMode": false,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "byzantium",
|
||||
"evmVersion": "constantinople",
|
||||
"optimizer": {
|
||||
"enabled": true,
|
||||
"runs": 1000000,
|
||||
|
@ -433,6 +433,50 @@ describe('ERC1155Proxy', () => {
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedFinalBalances);
|
||||
});
|
||||
it('should successfully transfer value to a smart contract and trigger its callback, when callback `data` is NULL', async () => {
|
||||
// setup test parameters
|
||||
const tokenHolders = [spender, receiverContract];
|
||||
const tokensToTransfer = fungibleTokens.slice(0, 1);
|
||||
const valuesToTransfer = [fungibleValueToTransferLarge];
|
||||
const valueMultiplier = valueMultiplierSmall;
|
||||
const totalValuesTransferred = _.map(valuesToTransfer, (value: BigNumber) => {
|
||||
return value.times(valueMultiplier);
|
||||
});
|
||||
// check balances before transfer
|
||||
const expectedInitialBalances = [spenderInitialFungibleBalance, receiverContractInitialFungibleBalance];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
|
||||
// execute transfer
|
||||
const nullReceiverCallbackData = '0x';
|
||||
const txReceipt = await erc1155ProxyWrapper.transferFromWithLogsAsync(
|
||||
spender,
|
||||
receiverContract,
|
||||
erc1155Contract.address,
|
||||
tokensToTransfer,
|
||||
valuesToTransfer,
|
||||
valueMultiplier,
|
||||
nullReceiverCallbackData,
|
||||
authorized,
|
||||
);
|
||||
// check receiver log ignored extra asset data
|
||||
expect(txReceipt.logs.length).to.be.equal(2);
|
||||
const receiverLog = txReceipt.logs[1] as LogWithDecodedArgs<
|
||||
DummyERC1155ReceiverBatchTokenReceivedEventArgs
|
||||
>;
|
||||
expect(receiverLog.args.operator).to.be.equal(erc1155Proxy.address);
|
||||
expect(receiverLog.args.from).to.be.equal(spender);
|
||||
expect(receiverLog.args.tokenIds.length).to.be.deep.equal(1);
|
||||
expect(receiverLog.args.tokenIds[0]).to.be.bignumber.equal(tokensToTransfer[0]);
|
||||
expect(receiverLog.args.tokenValues.length).to.be.deep.equal(1);
|
||||
expect(receiverLog.args.tokenValues[0]).to.be.bignumber.equal(totalValuesTransferred[0]);
|
||||
// note - if the `extraData` is ignored then the receiver log should ignore it as well.
|
||||
expect(receiverLog.args.data).to.be.deep.equal(nullReceiverCallbackData);
|
||||
// check balances after transfer
|
||||
const expectedFinalBalances = [
|
||||
expectedInitialBalances[0].minus(totalValuesTransferred[0]),
|
||||
expectedInitialBalances[1].plus(totalValuesTransferred[0]),
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedFinalBalances);
|
||||
});
|
||||
it('should successfully transfer value and ignore extra assetData', async () => {
|
||||
// setup test parameters
|
||||
const tokenHolders = [spender, receiverContract];
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { ERC1155MintableContract, Erc1155Wrapper } from '@0x/contracts-erc1155';
|
||||
import {
|
||||
artifacts as erc20Artifacts,
|
||||
DummyERC20TokenContract,
|
||||
@ -30,6 +31,7 @@ import * as _ from 'lodash';
|
||||
|
||||
import {
|
||||
artifacts,
|
||||
ERC1155ProxyWrapper,
|
||||
ERC20ProxyContract,
|
||||
ERC20Wrapper,
|
||||
ERC721ProxyContract,
|
||||
@ -77,6 +79,15 @@ describe('Asset Transfer Proxies', () => {
|
||||
let erc721AFromTokenId: BigNumber;
|
||||
let erc721BFromTokenId: BigNumber;
|
||||
|
||||
let erc1155Proxy: ERC721ProxyContract;
|
||||
let erc1155ProxyWrapper: ERC1155ProxyWrapper;
|
||||
let erc1155Contract: ERC1155MintableContract;
|
||||
let erc1155Contract2: ERC1155MintableContract;
|
||||
let erc1155Wrapper: Erc1155Wrapper;
|
||||
let erc1155Wrapper2: Erc1155Wrapper;
|
||||
let erc1155FungibleTokens: BigNumber[];
|
||||
let erc1155NonFungibleTokensOwnedBySpender: BigNumber[];
|
||||
|
||||
before(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
});
|
||||
@ -127,6 +138,22 @@ describe('Asset Transfer Proxies', () => {
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
|
||||
// Configure ERC115Proxy
|
||||
erc1155ProxyWrapper = new ERC1155ProxyWrapper(provider, usedAddresses, owner);
|
||||
erc1155Proxy = await erc1155ProxyWrapper.deployProxyAsync();
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc1155Proxy.addAuthorizedAddress.sendTransactionAsync(authorized, {
|
||||
from: owner,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc1155Proxy.addAuthorizedAddress.sendTransactionAsync(multiAssetProxy.address, {
|
||||
from: owner,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
|
||||
// Configure MultiAssetProxy
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await multiAssetProxy.addAuthorizedAddress.sendTransactionAsync(authorized, {
|
||||
@ -146,6 +173,12 @@ describe('Asset Transfer Proxies', () => {
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await multiAssetProxy.registerAssetProxy.sendTransactionAsync(erc1155Proxy.address, {
|
||||
from: owner,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
|
||||
// Deploy and configure ERC20 tokens
|
||||
const numDummyErc20ToDeploy = 2;
|
||||
@ -213,6 +246,22 @@ describe('Asset Transfer Proxies', () => {
|
||||
const erc721Balances = await erc721Wrapper.getBalancesAsync();
|
||||
erc721AFromTokenId = erc721Balances[fromAddress][erc721TokenA.address][0];
|
||||
erc721BFromTokenId = erc721Balances[fromAddress][erc721TokenB.address][0];
|
||||
|
||||
// Deploy & configure ERC1155 tokens and receiver
|
||||
[erc1155Wrapper, erc1155Wrapper2] = await erc1155ProxyWrapper.deployDummyContractsAsync();
|
||||
erc1155Contract = erc1155Wrapper.getContract();
|
||||
erc1155Contract2 = erc1155Wrapper2.getContract();
|
||||
await erc1155ProxyWrapper.setBalancesAndAllowancesAsync();
|
||||
erc1155FungibleTokens = erc1155ProxyWrapper.getFungibleTokenIds();
|
||||
const nonFungibleTokens = erc1155ProxyWrapper.getNonFungibleTokenIds();
|
||||
const tokenBalances = await erc1155ProxyWrapper.getBalancesAsync();
|
||||
erc1155NonFungibleTokensOwnedBySpender = [];
|
||||
_.each(nonFungibleTokens, (nonFungibleToken: BigNumber) => {
|
||||
const nonFungibleTokenAsString = nonFungibleToken.toString();
|
||||
const nonFungibleTokenHeldBySpender =
|
||||
tokenBalances.nonFungible[fromAddress][erc1155Contract.address][nonFungibleTokenAsString][0];
|
||||
erc1155NonFungibleTokensOwnedBySpender.push(nonFungibleTokenHeldBySpender);
|
||||
});
|
||||
});
|
||||
beforeEach(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
@ -944,6 +993,314 @@ describe('Asset Transfer Proxies', () => {
|
||||
expect(newOwnerFromAsset1).to.be.equal(toAddress);
|
||||
expect(newOwnerFromAsset2).to.be.equal(toAddress);
|
||||
});
|
||||
it('should transfer a fungible ERC1155 token', async () => {
|
||||
// setup test parameters
|
||||
const tokenHolders = [fromAddress, toAddress];
|
||||
const tokensToTransfer = erc1155FungibleTokens.slice(0, 1);
|
||||
const valuesToTransfer = [new BigNumber(25)];
|
||||
const valueMultiplier = new BigNumber(23);
|
||||
const receiverCallbackData = '0x0102030405';
|
||||
// check balances before transfer
|
||||
const expectedInitialBalances = [
|
||||
// from
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// to
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
|
||||
// encode erc1155 asset data
|
||||
const erc1155AssetData = assetDataUtils.encodeERC1155AssetData(
|
||||
erc1155Contract.address,
|
||||
tokensToTransfer,
|
||||
valuesToTransfer,
|
||||
receiverCallbackData,
|
||||
);
|
||||
// encode multi-asset data
|
||||
const multiAssetAmount = new BigNumber(5);
|
||||
const amounts = [valueMultiplier];
|
||||
const nestedAssetData = [erc1155AssetData];
|
||||
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
|
||||
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
|
||||
assetData,
|
||||
fromAddress,
|
||||
toAddress,
|
||||
multiAssetAmount,
|
||||
);
|
||||
// execute transfer
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await web3Wrapper.sendTransactionAsync({
|
||||
to: multiAssetProxy.address,
|
||||
data,
|
||||
from: authorized,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
// check balances
|
||||
const totalValueTransferred = valuesToTransfer[0].times(valueMultiplier).times(multiAssetAmount);
|
||||
const expectedFinalBalances = [
|
||||
// from
|
||||
expectedInitialBalances[0].minus(totalValueTransferred),
|
||||
// to
|
||||
expectedInitialBalances[1].plus(totalValueTransferred),
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedFinalBalances);
|
||||
});
|
||||
it('should successfully transfer multiple fungible tokens of the same ERC1155 contract', async () => {
|
||||
// setup test parameters
|
||||
const tokenHolders = [fromAddress, toAddress];
|
||||
const tokensToTransfer = erc1155FungibleTokens.slice(0, 3);
|
||||
const valuesToTransfer = [new BigNumber(25), new BigNumber(35), new BigNumber(45)];
|
||||
const valueMultiplier = new BigNumber(23);
|
||||
const receiverCallbackData = '0x0102030405';
|
||||
// check balances before transfer
|
||||
const expectedInitialBalances = [
|
||||
// from
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// to
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
|
||||
// encode erc1155 asset data
|
||||
const erc1155AssetData = assetDataUtils.encodeERC1155AssetData(
|
||||
erc1155Contract.address,
|
||||
tokensToTransfer,
|
||||
valuesToTransfer,
|
||||
receiverCallbackData,
|
||||
);
|
||||
// encode multi-asset data
|
||||
const multiAssetAmount = new BigNumber(5);
|
||||
const amounts = [valueMultiplier];
|
||||
const nestedAssetData = [erc1155AssetData];
|
||||
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
|
||||
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
|
||||
assetData,
|
||||
fromAddress,
|
||||
toAddress,
|
||||
multiAssetAmount,
|
||||
);
|
||||
// execute transfer
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await web3Wrapper.sendTransactionAsync({
|
||||
to: multiAssetProxy.address,
|
||||
data,
|
||||
from: authorized,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
// check balances
|
||||
const totalValuesTransferred = _.map(valuesToTransfer, (value: BigNumber) => {
|
||||
return value.times(valueMultiplier).times(multiAssetAmount);
|
||||
});
|
||||
const expectedFinalBalances = [
|
||||
// from
|
||||
expectedInitialBalances[0].minus(totalValuesTransferred[0]),
|
||||
expectedInitialBalances[1].minus(totalValuesTransferred[1]),
|
||||
expectedInitialBalances[2].minus(totalValuesTransferred[2]),
|
||||
// to
|
||||
expectedInitialBalances[3].plus(totalValuesTransferred[0]),
|
||||
expectedInitialBalances[4].plus(totalValuesTransferred[1]),
|
||||
expectedInitialBalances[5].plus(totalValuesTransferred[2]),
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedFinalBalances);
|
||||
});
|
||||
it('should successfully transfer multiple fungible/non-fungible tokens of the same ERC1155 contract', async () => {
|
||||
// setup test parameters
|
||||
const tokenHolders = [fromAddress, toAddress];
|
||||
const fungibleTokensToTransfer = erc1155FungibleTokens.slice(0, 1);
|
||||
const nonFungibleTokensToTransfer = erc1155NonFungibleTokensOwnedBySpender.slice(0, 1);
|
||||
const tokensToTransfer = fungibleTokensToTransfer.concat(nonFungibleTokensToTransfer);
|
||||
const valuesToTransfer = [new BigNumber(25), new BigNumber(1)];
|
||||
const valueMultiplier = new BigNumber(1);
|
||||
const receiverCallbackData = '0x0102030405';
|
||||
// check balances before transfer
|
||||
const nftOwnerBalance = new BigNumber(1);
|
||||
const nftNotOwnerBalance = new BigNumber(0);
|
||||
const expectedInitialBalances = [
|
||||
// from
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
nftOwnerBalance,
|
||||
// to
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
nftNotOwnerBalance,
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
|
||||
// encode erc1155 asset data
|
||||
const erc1155AssetData = assetDataUtils.encodeERC1155AssetData(
|
||||
erc1155Contract.address,
|
||||
tokensToTransfer,
|
||||
valuesToTransfer,
|
||||
receiverCallbackData,
|
||||
);
|
||||
// encode multi-asset data
|
||||
const multiAssetAmount = new BigNumber(1);
|
||||
const amounts = [valueMultiplier];
|
||||
const nestedAssetData = [erc1155AssetData];
|
||||
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
|
||||
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
|
||||
assetData,
|
||||
fromAddress,
|
||||
toAddress,
|
||||
multiAssetAmount,
|
||||
);
|
||||
// execute transfer
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await web3Wrapper.sendTransactionAsync({
|
||||
to: multiAssetProxy.address,
|
||||
data,
|
||||
from: authorized,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
// check balances
|
||||
const totalValuesTransferred = _.map(valuesToTransfer, (value: BigNumber) => {
|
||||
return value.times(valueMultiplier).times(multiAssetAmount);
|
||||
});
|
||||
const expectedFinalBalances = [
|
||||
// from
|
||||
expectedInitialBalances[0].minus(totalValuesTransferred[0]),
|
||||
expectedInitialBalances[1].minus(totalValuesTransferred[1]),
|
||||
// to
|
||||
expectedInitialBalances[2].plus(totalValuesTransferred[0]),
|
||||
expectedInitialBalances[3].plus(totalValuesTransferred[1]),
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedFinalBalances);
|
||||
});
|
||||
it('should successfully transfer multiple different ERC1155 tokens', async () => {
|
||||
// setup test parameters
|
||||
const tokenHolders = [fromAddress, toAddress];
|
||||
const tokensToTransfer = erc1155FungibleTokens.slice(0, 1);
|
||||
const valuesToTransfer = [new BigNumber(25)];
|
||||
const valueMultiplier = new BigNumber(23);
|
||||
const receiverCallbackData = '0x0102030405';
|
||||
// check balances before transfer
|
||||
const expectedInitialBalances = [
|
||||
// from
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// to
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
|
||||
await erc1155Wrapper2.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
|
||||
// encode erc1155 asset data
|
||||
const erc1155AssetData1 = assetDataUtils.encodeERC1155AssetData(
|
||||
erc1155Contract.address,
|
||||
tokensToTransfer,
|
||||
valuesToTransfer,
|
||||
receiverCallbackData,
|
||||
);
|
||||
const erc1155AssetData2 = assetDataUtils.encodeERC1155AssetData(
|
||||
erc1155Contract2.address,
|
||||
tokensToTransfer,
|
||||
valuesToTransfer,
|
||||
receiverCallbackData,
|
||||
);
|
||||
// encode multi-asset data
|
||||
const multiAssetAmount = new BigNumber(5);
|
||||
const amounts = [valueMultiplier, valueMultiplier];
|
||||
const nestedAssetData = [erc1155AssetData1, erc1155AssetData2];
|
||||
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
|
||||
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
|
||||
assetData,
|
||||
fromAddress,
|
||||
toAddress,
|
||||
multiAssetAmount,
|
||||
);
|
||||
// execute transfer
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await web3Wrapper.sendTransactionAsync({
|
||||
to: multiAssetProxy.address,
|
||||
data,
|
||||
from: authorized,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
// check balances
|
||||
const totalValueTransferred = valuesToTransfer[0].times(valueMultiplier).times(multiAssetAmount);
|
||||
const expectedFinalBalances = [
|
||||
// from
|
||||
expectedInitialBalances[0].minus(totalValueTransferred),
|
||||
// to
|
||||
expectedInitialBalances[1].plus(totalValueTransferred),
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedFinalBalances);
|
||||
await erc1155Wrapper2.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedFinalBalances);
|
||||
});
|
||||
it('should successfully transfer a combination of ERC20, ERC721, and ERC1155 tokens', async () => {
|
||||
// setup test parameters
|
||||
const inputAmount = new BigNumber(1);
|
||||
const erc20Amount = new BigNumber(10);
|
||||
const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address);
|
||||
const erc721Amount = new BigNumber(1);
|
||||
const erc721AssetData = assetDataUtils.encodeERC721AssetData(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(
|
||||
erc1155Contract.address,
|
||||
erc1155TokensToTransfer,
|
||||
erc1155ValuesToTransfer,
|
||||
erc1155ReceiverCallbackData,
|
||||
);
|
||||
const amounts = [erc20Amount, erc721Amount, erc1155Amount];
|
||||
const nestedAssetData = [erc20AssetData, erc721AssetData, erc1155AssetData];
|
||||
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
|
||||
const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData(
|
||||
assetData,
|
||||
fromAddress,
|
||||
toAddress,
|
||||
inputAmount,
|
||||
);
|
||||
// check balances before transfer
|
||||
const erc20Balances = await erc20Wrapper.getBalancesAsync();
|
||||
const ownerFromAsset = await erc721TokenA.ownerOf.callAsync(erc721AFromTokenId);
|
||||
expect(ownerFromAsset).to.be.equal(fromAddress);
|
||||
const erc1155ExpectedInitialBalances = [
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(
|
||||
erc1155TokenHolders,
|
||||
erc1155TokensToTransfer,
|
||||
erc1155ExpectedInitialBalances,
|
||||
);
|
||||
// execute transfer
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await web3Wrapper.sendTransactionAsync({
|
||||
to: multiAssetProxy.address,
|
||||
data,
|
||||
from: authorized,
|
||||
gas: 1000000,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
// check balances after transfer
|
||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||
const totalAmount = inputAmount.times(erc20Amount);
|
||||
expect(newBalances[fromAddress][erc20TokenA.address]).to.be.bignumber.equal(
|
||||
erc20Balances[fromAddress][erc20TokenA.address].minus(totalAmount),
|
||||
);
|
||||
expect(newBalances[toAddress][erc20TokenA.address]).to.be.bignumber.equal(
|
||||
erc20Balances[toAddress][erc20TokenA.address].plus(totalAmount),
|
||||
);
|
||||
const newOwnerFromAsset = await erc721TokenA.ownerOf.callAsync(erc721AFromTokenId);
|
||||
expect(newOwnerFromAsset).to.be.equal(toAddress);
|
||||
const erc1155TotalValueTransferred = erc1155ValuesToTransfer[0].times(erc1155Amount).times(inputAmount);
|
||||
const expectedFinalBalances = [
|
||||
erc1155ExpectedInitialBalances[0].minus(erc1155TotalValueTransferred),
|
||||
erc1155ExpectedInitialBalances[1].plus(erc1155TotalValueTransferred),
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(
|
||||
erc1155TokenHolders,
|
||||
erc1155TokensToTransfer,
|
||||
expectedFinalBalances,
|
||||
);
|
||||
});
|
||||
it('should successfully transfer a combination of ERC20 and ERC721 tokens', async () => {
|
||||
const inputAmount = new BigNumber(1);
|
||||
const erc20Amount = new BigNumber(10);
|
||||
|
@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"version": "0.0.1",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Created Coordinator package"
|
||||
@ -12,6 +12,10 @@
|
||||
{
|
||||
"note": "Add `SignatureType.Invalid`",
|
||||
"pr": 1705
|
||||
},
|
||||
{
|
||||
"note": "Set `evmVersion` to `constantinople`",
|
||||
"pr": 1707
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": true,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "byzantium",
|
||||
"evmVersion": "constantinople",
|
||||
"optimizer": {
|
||||
"enabled": true,
|
||||
"runs": 1000000,
|
||||
|
@ -3,7 +3,7 @@
|
||||
"contractsDir": "contracts",
|
||||
"useDockerisedSolc": true,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "byzantium",
|
||||
"evmVersion": "constantinople",
|
||||
"optimizer": { "enabled": true, "runs": 1000000 },
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
|
@ -2,10 +2,6 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Set evmVersion to byzantium",
|
||||
"pr": 1678
|
||||
},
|
||||
{
|
||||
"note": "Upgrade contracts to Solidity 0.5.5",
|
||||
"pr": 1682
|
||||
|
@ -4,7 +4,7 @@
|
||||
"useDockerisedSolc": true,
|
||||
"isOfflineMode": false,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "byzantium",
|
||||
"evmVersion": "constantinople",
|
||||
"optimizer": {
|
||||
"enabled": true,
|
||||
"runs": 1000000,
|
||||
|
@ -2,10 +2,6 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Set evmVersion to byzantium",
|
||||
"pr": 1678
|
||||
},
|
||||
{
|
||||
"note": "Upgrade contracts to Solidity 0.5.5",
|
||||
"pr": 1682
|
||||
|
@ -4,7 +4,7 @@
|
||||
"useDockerisedSolc": true,
|
||||
"isOfflineMode": false,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "byzantium",
|
||||
"evmVersion": "constantinople",
|
||||
"optimizer": {
|
||||
"enabled": true,
|
||||
"runs": 1000000,
|
||||
|
@ -2,10 +2,6 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Set evmVersion to byzantium",
|
||||
"pr": 1678
|
||||
},
|
||||
{
|
||||
"note": "Do not reexport external dependencies",
|
||||
"pr": 1682
|
||||
|
@ -4,7 +4,7 @@
|
||||
"useDockerisedSolc": true,
|
||||
"isOfflineMode": false,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "byzantium",
|
||||
"evmVersion": "constantinople",
|
||||
"optimizer": {
|
||||
"enabled": true,
|
||||
"runs": 1000000,
|
||||
|
@ -2,10 +2,6 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Set evmVersion to byzantium",
|
||||
"pr": 1678
|
||||
},
|
||||
{
|
||||
"note": "Upgrade contracts to Solidity 0.5.5",
|
||||
"pr": 1682
|
||||
|
@ -4,7 +4,7 @@
|
||||
"useDockerisedSolc": true,
|
||||
"isOfflineMode": false,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "byzantium",
|
||||
"evmVersion": "constantinople",
|
||||
"optimizer": {
|
||||
"enabled": true,
|
||||
"runs": 1000000,
|
||||
|
@ -2,10 +2,6 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Set evmVersion to byzantium",
|
||||
"pr": 1678
|
||||
},
|
||||
{
|
||||
"note": "Do not reexport external dependencies",
|
||||
"pr": 1682
|
||||
@ -13,6 +9,10 @@
|
||||
{
|
||||
"note": "Upgrade contracts to Solidity 0.5.5",
|
||||
"pr": 1682
|
||||
},
|
||||
{
|
||||
"note": "Integration testing for ERC1155Proxy",
|
||||
"pr": 1673
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -4,7 +4,7 @@
|
||||
"useDockerisedSolc": true,
|
||||
"isOfflineMode": false,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "byzantium",
|
||||
"evmVersion": "constantinople",
|
||||
"optimizer": {
|
||||
"enabled": true,
|
||||
"runs": 1000000,
|
||||
|
@ -71,6 +71,7 @@
|
||||
"@0x/contracts-asset-proxy": "^1.0.9",
|
||||
"@0x/contracts-erc20": "^1.0.9",
|
||||
"@0x/contracts-erc721": "^1.0.9",
|
||||
"@0x/contracts-erc1155": "^1.0.0",
|
||||
"@0x/contracts-exchange-libs": "^1.1.3",
|
||||
"@0x/contracts-utils": "^2.0.8",
|
||||
"@0x/order-utils": "^7.0.2",
|
||||
|
@ -1,11 +1,13 @@
|
||||
import {
|
||||
artifacts as proxyArtifacts,
|
||||
ERC1155ProxyWrapper,
|
||||
ERC20ProxyContract,
|
||||
ERC20Wrapper,
|
||||
ERC721ProxyContract,
|
||||
ERC721Wrapper,
|
||||
MultiAssetProxyContract,
|
||||
} from '@0x/contracts-asset-proxy';
|
||||
import { ERC1155MintableContract } from '@0x/contracts-erc1155';
|
||||
import {
|
||||
artifacts as erc20Artifacts,
|
||||
DummyERC20TokenContract,
|
||||
@ -36,6 +38,7 @@ import { LogWithDecodedArgs } from 'ethereum-types';
|
||||
import ethUtil = require('ethereumjs-util');
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { Erc1155Wrapper } from '../../erc1155/lib/src';
|
||||
import {
|
||||
artifacts,
|
||||
ExchangeCancelEventArgs,
|
||||
@ -64,19 +67,26 @@ describe('Exchange core', () => {
|
||||
let exchange: ExchangeContract;
|
||||
let erc20Proxy: ERC20ProxyContract;
|
||||
let erc721Proxy: ERC721ProxyContract;
|
||||
let erc1155Proxy: ERC721ProxyContract;
|
||||
let multiAssetProxy: MultiAssetProxyContract;
|
||||
let maliciousWallet: TestStaticCallReceiverContract;
|
||||
let maliciousValidator: TestStaticCallReceiverContract;
|
||||
let erc1155Contract: ERC1155MintableContract;
|
||||
|
||||
let signedOrder: SignedOrder;
|
||||
let erc20Balances: ERC20BalancesByOwner;
|
||||
let exchangeWrapper: ExchangeWrapper;
|
||||
let erc20Wrapper: ERC20Wrapper;
|
||||
let erc721Wrapper: ERC721Wrapper;
|
||||
let erc1155Wrapper: Erc1155Wrapper;
|
||||
let erc1155ProxyWrapper: ERC1155ProxyWrapper;
|
||||
let orderFactory: OrderFactory;
|
||||
|
||||
let erc721MakerAssetIds: BigNumber[];
|
||||
let erc721TakerAssetIds: BigNumber[];
|
||||
let erc1155FungibleTokens: BigNumber[];
|
||||
let erc1155NonFungibleTokensOwnedByMaker: BigNumber[];
|
||||
let erc1155NonFungibleTokensOwnedByTaker: BigNumber[];
|
||||
|
||||
let defaultMakerAssetAddress: string;
|
||||
let defaultTakerAssetAddress: string;
|
||||
@ -93,6 +103,7 @@ describe('Exchange core', () => {
|
||||
|
||||
erc20Wrapper = new ERC20Wrapper(provider, usedAddresses, owner);
|
||||
erc721Wrapper = new ERC721Wrapper(provider, usedAddresses, owner);
|
||||
erc1155ProxyWrapper = new ERC1155ProxyWrapper(provider, usedAddresses, owner);
|
||||
|
||||
// Deploy AssetProxies, Exchange, tokens, and malicious contracts
|
||||
erc20Proxy = await erc20Wrapper.deployProxyAsync();
|
||||
@ -108,6 +119,9 @@ describe('Exchange core', () => {
|
||||
constants.DUMMY_TOKEN_DECIMALS,
|
||||
);
|
||||
[erc721Token] = await erc721Wrapper.deployDummyTokensAsync();
|
||||
erc1155Proxy = await erc1155ProxyWrapper.deployProxyAsync();
|
||||
[erc1155Wrapper] = await erc1155ProxyWrapper.deployDummyContractsAsync();
|
||||
erc1155Contract = erc1155Wrapper.getContract();
|
||||
exchange = await ExchangeContract.deployFrom0xArtifactAsync(
|
||||
artifacts.Exchange,
|
||||
provider,
|
||||
@ -154,6 +168,20 @@ describe('Exchange core', () => {
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
|
||||
// Configure ERC1155Proxy
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc1155Proxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, {
|
||||
from: owner,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc1155Proxy.addAuthorizedAddress.sendTransactionAsync(multiAssetProxy.address, {
|
||||
from: owner,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
|
||||
// Configure MultiAssetProxy
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await multiAssetProxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, {
|
||||
@ -178,6 +206,7 @@ describe('Exchange core', () => {
|
||||
exchangeWrapper = new ExchangeWrapper(exchange, provider);
|
||||
await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, owner);
|
||||
await exchangeWrapper.registerAssetProxyAsync(erc721Proxy.address, owner);
|
||||
await exchangeWrapper.registerAssetProxyAsync(erc1155Proxy.address, owner);
|
||||
await exchangeWrapper.registerAssetProxyAsync(multiAssetProxy.address, owner);
|
||||
|
||||
// Configure ERC20 tokens
|
||||
@ -189,6 +218,23 @@ describe('Exchange core', () => {
|
||||
erc721MakerAssetIds = erc721Balances[makerAddress][erc721Token.address];
|
||||
erc721TakerAssetIds = erc721Balances[takerAddress][erc721Token.address];
|
||||
|
||||
// Configure ERC1155 tokens
|
||||
await erc1155ProxyWrapper.setBalancesAndAllowancesAsync();
|
||||
erc1155FungibleTokens = erc1155ProxyWrapper.getFungibleTokenIds();
|
||||
const nonFungibleTokens = erc1155ProxyWrapper.getNonFungibleTokenIds();
|
||||
const tokenBalances = await erc1155ProxyWrapper.getBalancesAsync();
|
||||
erc1155NonFungibleTokensOwnedByMaker = [];
|
||||
erc1155NonFungibleTokensOwnedByTaker = [];
|
||||
_.each(nonFungibleTokens, (nonFungibleToken: BigNumber) => {
|
||||
const nonFungibleTokenAsString = nonFungibleToken.toString();
|
||||
const nonFungibleTokenHeldByMaker =
|
||||
tokenBalances.nonFungible[makerAddress][erc1155Contract.address][nonFungibleTokenAsString][0];
|
||||
erc1155NonFungibleTokensOwnedByMaker.push(nonFungibleTokenHeldByMaker);
|
||||
const nonFungibleTokenHeldByTaker =
|
||||
tokenBalances.nonFungible[takerAddress][erc1155Contract.address][nonFungibleTokenAsString][0];
|
||||
erc1155NonFungibleTokensOwnedByTaker.push(nonFungibleTokenHeldByTaker);
|
||||
});
|
||||
|
||||
// Configure order defaults
|
||||
defaultMakerAssetAddress = erc20TokenA.address;
|
||||
defaultTakerAssetAddress = erc20TokenB.address;
|
||||
@ -1040,6 +1086,435 @@ describe('Exchange core', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('Testing exchange of erc1155 assets', () => {
|
||||
it('should allow a single fungible erc1155 asset to be exchanged for another', async () => {
|
||||
// setup test parameters
|
||||
const tokenHolders = [makerAddress, takerAddress];
|
||||
const makerAssetsToTransfer = erc1155FungibleTokens.slice(0, 1);
|
||||
const takerAssetsToTransfer = erc1155FungibleTokens.slice(1, 2);
|
||||
const makerValuesToTransfer = [new BigNumber(500)];
|
||||
const takerValuesToTransfer = [new BigNumber(200)];
|
||||
const tokensToTransfer = makerAssetsToTransfer.concat(takerAssetsToTransfer);
|
||||
const makerAssetAmount = new BigNumber(1);
|
||||
const takerAssetAmount = new BigNumber(1);
|
||||
const totalMakerValuesTransferred = _.map(makerValuesToTransfer, (value: BigNumber) => {
|
||||
return value.times(makerAssetAmount);
|
||||
});
|
||||
const totalTakerValuesTransferred = _.map(takerValuesToTransfer, (value: BigNumber) => {
|
||||
return value.times(takerAssetAmount);
|
||||
});
|
||||
const receiverCallbackData = '0x';
|
||||
const makerAssetData = assetDataUtils.encodeERC1155AssetData(
|
||||
erc1155Contract.address,
|
||||
makerAssetsToTransfer,
|
||||
makerValuesToTransfer,
|
||||
receiverCallbackData,
|
||||
);
|
||||
const takerAssetData = assetDataUtils.encodeERC1155AssetData(
|
||||
erc1155Contract.address,
|
||||
takerAssetsToTransfer,
|
||||
takerValuesToTransfer,
|
||||
receiverCallbackData,
|
||||
);
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetData,
|
||||
takerAssetData,
|
||||
makerAssetAmount,
|
||||
takerAssetAmount,
|
||||
makerFee: constants.ZERO_AMOUNT,
|
||||
takerFee: constants.ZERO_AMOUNT,
|
||||
});
|
||||
const takerAssetFillAmount = new BigNumber(1);
|
||||
// check balances before transfer
|
||||
const expectedInitialBalances = [
|
||||
// makerAddress / makerToken
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// makerAddress / takerToken
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// takerAddress / makerToken
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// takerAddress / takerToken
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
|
||||
// execute transfer
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
||||
takerAssetFillAmount,
|
||||
});
|
||||
// check balances after transfer
|
||||
const expectedFinalBalances = [
|
||||
// makerAddress / makerToken
|
||||
expectedInitialBalances[0].minus(totalMakerValuesTransferred[0]),
|
||||
// makerAddress / takerToken
|
||||
expectedInitialBalances[1].plus(totalTakerValuesTransferred[0]),
|
||||
// takerAddress / makerToken
|
||||
expectedInitialBalances[2].plus(totalMakerValuesTransferred[0]),
|
||||
// takerAddress / takerToken
|
||||
expectedInitialBalances[3].minus(totalTakerValuesTransferred[0]),
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedFinalBalances);
|
||||
});
|
||||
it('should allow a single non-fungible erc1155 asset to be exchanged for another', async () => {
|
||||
// setup test parameters
|
||||
const tokenHolders = [makerAddress, takerAddress];
|
||||
const makerAssetsToTransfer = erc1155NonFungibleTokensOwnedByMaker.slice(0, 1);
|
||||
const takerAssetsToTransfer = erc1155NonFungibleTokensOwnedByTaker.slice(0, 1);
|
||||
const makerValuesToTransfer = [new BigNumber(1)];
|
||||
const takerValuesToTransfer = [new BigNumber(1)];
|
||||
const tokensToTransfer = makerAssetsToTransfer.concat(takerAssetsToTransfer);
|
||||
const makerAssetAmount = new BigNumber(1);
|
||||
const takerAssetAmount = new BigNumber(1);
|
||||
const totalMakerValuesTransferred = _.map(makerValuesToTransfer, (value: BigNumber) => {
|
||||
return value.times(makerAssetAmount);
|
||||
});
|
||||
const totalTakerValuesTransferred = _.map(takerValuesToTransfer, (value: BigNumber) => {
|
||||
return value.times(takerAssetAmount);
|
||||
});
|
||||
const receiverCallbackData = '0x';
|
||||
const makerAssetData = assetDataUtils.encodeERC1155AssetData(
|
||||
erc1155Contract.address,
|
||||
makerAssetsToTransfer,
|
||||
makerValuesToTransfer,
|
||||
receiverCallbackData,
|
||||
);
|
||||
const takerAssetData = assetDataUtils.encodeERC1155AssetData(
|
||||
erc1155Contract.address,
|
||||
takerAssetsToTransfer,
|
||||
takerValuesToTransfer,
|
||||
receiverCallbackData,
|
||||
);
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetData,
|
||||
takerAssetData,
|
||||
makerAssetAmount,
|
||||
takerAssetAmount,
|
||||
makerFee: constants.ZERO_AMOUNT,
|
||||
takerFee: constants.ZERO_AMOUNT,
|
||||
});
|
||||
const takerAssetFillAmount = new BigNumber(1);
|
||||
// check balances before transfer
|
||||
const nftOwnerBalance = new BigNumber(1);
|
||||
const nftNotOwnerBalance = new BigNumber(0);
|
||||
const expectedInitialBalances = [
|
||||
// makerAddress / makerToken
|
||||
nftOwnerBalance,
|
||||
// makerAddress / takerToken
|
||||
nftNotOwnerBalance,
|
||||
// takerAddress / makerToken
|
||||
nftNotOwnerBalance,
|
||||
// takerAddress / takerToken
|
||||
nftOwnerBalance,
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
|
||||
// execute transfer
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
||||
takerAssetFillAmount,
|
||||
});
|
||||
// check balances after transfer
|
||||
const expectedFinalBalances = [
|
||||
// makerAddress / makerToken
|
||||
expectedInitialBalances[0].minus(totalMakerValuesTransferred[0]),
|
||||
// makerAddress / takerToken
|
||||
expectedInitialBalances[1].plus(totalTakerValuesTransferred[0]),
|
||||
// takerAddress / makerToken
|
||||
expectedInitialBalances[2].plus(totalMakerValuesTransferred[0]),
|
||||
// takerAddress / takerToken
|
||||
expectedInitialBalances[3].minus(totalTakerValuesTransferred[0]),
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedFinalBalances);
|
||||
});
|
||||
it('should allow multiple erc1155 assets to be exchanged for a single asset', async () => {
|
||||
// setup test parameters
|
||||
const tokenHolders = [makerAddress, takerAddress];
|
||||
const makerAssetsToTransfer = erc1155FungibleTokens.slice(0, 3);
|
||||
const takerAssetsToTransfer = erc1155NonFungibleTokensOwnedByTaker.slice(0, 1);
|
||||
const makerValuesToTransfer = [new BigNumber(500), new BigNumber(700), new BigNumber(900)];
|
||||
const takerValuesToTransfer = [new BigNumber(1)];
|
||||
const tokensToTransfer = makerAssetsToTransfer.concat(takerAssetsToTransfer);
|
||||
const makerAssetAmount = new BigNumber(1);
|
||||
const takerAssetAmount = new BigNumber(1);
|
||||
const totalMakerValuesTransferred = _.map(makerValuesToTransfer, (value: BigNumber) => {
|
||||
return value.times(makerAssetAmount);
|
||||
});
|
||||
const totalTakerValuesTransferred = _.map(takerValuesToTransfer, (value: BigNumber) => {
|
||||
return value.times(takerAssetAmount);
|
||||
});
|
||||
const receiverCallbackData = '0x';
|
||||
const makerAssetData = assetDataUtils.encodeERC1155AssetData(
|
||||
erc1155Contract.address,
|
||||
makerAssetsToTransfer,
|
||||
makerValuesToTransfer,
|
||||
receiverCallbackData,
|
||||
);
|
||||
const takerAssetData = assetDataUtils.encodeERC1155AssetData(
|
||||
erc1155Contract.address,
|
||||
takerAssetsToTransfer,
|
||||
takerValuesToTransfer,
|
||||
receiverCallbackData,
|
||||
);
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetData,
|
||||
takerAssetData,
|
||||
makerAssetAmount,
|
||||
takerAssetAmount,
|
||||
makerFee: constants.ZERO_AMOUNT,
|
||||
takerFee: constants.ZERO_AMOUNT,
|
||||
});
|
||||
const takerAssetFillAmount = new BigNumber(1);
|
||||
// check balances before transfer
|
||||
const nftOwnerBalance = new BigNumber(1);
|
||||
const nftNotOwnerBalance = new BigNumber(0);
|
||||
const expectedInitialBalances = [
|
||||
// makerAddress / makerToken[0]
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// makerAddress / makerToken[1]
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// makerAddress / makerToken[2]
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// makerAddress / takerToken
|
||||
nftNotOwnerBalance,
|
||||
// takerAddress / makerToken[0]
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// takerAddress / makerToken[1]
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// takerAddress / makerToken[2]
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// takerAddress / takerToken
|
||||
nftOwnerBalance,
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
|
||||
// execute transfer
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
||||
takerAssetFillAmount,
|
||||
});
|
||||
// check balances after transfer
|
||||
const expectedFinalBalances = [
|
||||
// makerAddress / makerToken[0]
|
||||
expectedInitialBalances[0].minus(totalMakerValuesTransferred[0]),
|
||||
// makerAddress / makerToken[1]
|
||||
expectedInitialBalances[1].minus(totalMakerValuesTransferred[1]),
|
||||
// makerAddress / makerToken[2]
|
||||
expectedInitialBalances[2].minus(totalMakerValuesTransferred[2]),
|
||||
// makerAddress / takerToken
|
||||
expectedInitialBalances[3].plus(totalTakerValuesTransferred[0]),
|
||||
// takerAddress / makerToken[0]
|
||||
expectedInitialBalances[4].plus(totalMakerValuesTransferred[0]),
|
||||
// takerAddress / makerToken[1]
|
||||
expectedInitialBalances[5].plus(totalMakerValuesTransferred[1]),
|
||||
// takerAddress / makerToken[2]
|
||||
expectedInitialBalances[6].plus(totalMakerValuesTransferred[2]),
|
||||
// takerAddress / takerToken
|
||||
expectedInitialBalances[7].minus(totalTakerValuesTransferred[0]),
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedFinalBalances);
|
||||
});
|
||||
it('should allow multiple erc1155 assets to be exchanged for multiple erc1155 assets, mixed fungible/non-fungible', async () => {
|
||||
// setup test parameters
|
||||
// the maker is trading two fungibles & one non-fungible
|
||||
// the taker is trading one fungible & two non-fungibles
|
||||
const tokenHolders = [makerAddress, takerAddress];
|
||||
const makerFungibleAssetsToTransfer = erc1155FungibleTokens.slice(0, 2);
|
||||
const makerNonFungibleAssetsToTransfer = erc1155NonFungibleTokensOwnedByMaker.slice(0, 1);
|
||||
const makerAssetsToTransfer = makerFungibleAssetsToTransfer.concat(makerNonFungibleAssetsToTransfer);
|
||||
const takerFungibleAssetsToTransfer = erc1155FungibleTokens.slice(2, 3);
|
||||
const takerNonFungibleAssetsToTransfer = erc1155NonFungibleTokensOwnedByTaker.slice(0, 2);
|
||||
const takerAssetsToTransfer = takerFungibleAssetsToTransfer.concat(takerNonFungibleAssetsToTransfer);
|
||||
const makerValuesToTransfer = [new BigNumber(500), new BigNumber(700), new BigNumber(1)];
|
||||
const takerValuesToTransfer = [new BigNumber(900), new BigNumber(1), new BigNumber(1)];
|
||||
const tokensToTransfer = makerAssetsToTransfer.concat(takerAssetsToTransfer);
|
||||
const makerAssetAmount = new BigNumber(1);
|
||||
const takerAssetAmount = new BigNumber(1);
|
||||
const totalMakerValuesTransferred = _.map(makerValuesToTransfer, (value: BigNumber) => {
|
||||
return value.times(makerAssetAmount);
|
||||
});
|
||||
const totalTakerValuesTransferred = _.map(takerValuesToTransfer, (value: BigNumber) => {
|
||||
return value.times(takerAssetAmount);
|
||||
});
|
||||
const receiverCallbackData = '0x';
|
||||
const makerAssetData = assetDataUtils.encodeERC1155AssetData(
|
||||
erc1155Contract.address,
|
||||
makerAssetsToTransfer,
|
||||
makerValuesToTransfer,
|
||||
receiverCallbackData,
|
||||
);
|
||||
const takerAssetData = assetDataUtils.encodeERC1155AssetData(
|
||||
erc1155Contract.address,
|
||||
takerAssetsToTransfer,
|
||||
takerValuesToTransfer,
|
||||
receiverCallbackData,
|
||||
);
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetData,
|
||||
takerAssetData,
|
||||
makerAssetAmount,
|
||||
takerAssetAmount,
|
||||
makerFee: constants.ZERO_AMOUNT,
|
||||
takerFee: constants.ZERO_AMOUNT,
|
||||
});
|
||||
const takerAssetFillAmount = new BigNumber(1);
|
||||
// check balances before transfer
|
||||
const nftOwnerBalance = new BigNumber(1);
|
||||
const nftNotOwnerBalance = new BigNumber(0);
|
||||
const expectedInitialBalances = [
|
||||
// makerAddress / makerToken[0]
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// makerAddress / makerToken[1]
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// makerAddress / makerToken[2]
|
||||
nftOwnerBalance,
|
||||
// makerAddress / takerToken[0]
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// makerAddress / takerToken[1]
|
||||
nftNotOwnerBalance,
|
||||
// makerAddress / takerToken[2]
|
||||
nftNotOwnerBalance,
|
||||
// takerAddress / makerToken[0]
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// takerAddress / makerToken[1]
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// takerAddress / makerToken[2]
|
||||
nftNotOwnerBalance,
|
||||
// takerAddress / takerToken[0]
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// takerAddress / takerToken[1]
|
||||
nftOwnerBalance,
|
||||
// takerAddress / takerToken[2]
|
||||
nftOwnerBalance,
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
|
||||
// execute transfer
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
||||
takerAssetFillAmount,
|
||||
});
|
||||
// check balances after transfer
|
||||
const expectedFinalBalances = [
|
||||
// makerAddress / makerToken[0]
|
||||
expectedInitialBalances[0].minus(totalMakerValuesTransferred[0]),
|
||||
// makerAddress / makerToken[1]
|
||||
expectedInitialBalances[1].minus(totalMakerValuesTransferred[1]),
|
||||
// makerAddress / makerToken[2]
|
||||
expectedInitialBalances[2].minus(totalMakerValuesTransferred[2]),
|
||||
// makerAddress / takerToken[0]
|
||||
expectedInitialBalances[3].plus(totalTakerValuesTransferred[0]),
|
||||
// makerAddress / takerToken[1]
|
||||
expectedInitialBalances[4].plus(totalTakerValuesTransferred[1]),
|
||||
// makerAddress / takerToken[2]
|
||||
expectedInitialBalances[5].plus(totalTakerValuesTransferred[2]),
|
||||
// takerAddress / makerToken[0]
|
||||
expectedInitialBalances[6].plus(totalMakerValuesTransferred[0]),
|
||||
// takerAddress / makerToken[1]
|
||||
expectedInitialBalances[7].plus(totalMakerValuesTransferred[1]),
|
||||
// takerAddress / makerToken[2]
|
||||
expectedInitialBalances[8].plus(totalMakerValuesTransferred[2]),
|
||||
// takerAddress / takerToken[0]
|
||||
expectedInitialBalances[9].minus(totalTakerValuesTransferred[0]),
|
||||
// takerAddress / takerToken[1]
|
||||
expectedInitialBalances[10].minus(totalTakerValuesTransferred[1]),
|
||||
// takerAddress / takerToken[2]
|
||||
expectedInitialBalances[11].minus(totalTakerValuesTransferred[2]),
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedFinalBalances);
|
||||
});
|
||||
it('should allow an order exchanging erc1155 assets to be partially filled', async () => {
|
||||
// NOTICE:
|
||||
// As-per the eip1155 standard, there is no way to distinguish between a fungible or non-fungible erc1155 assets.
|
||||
// Hence we cannot force partial fills to fail if there is a non-fungible asset (which should be fill or kill).
|
||||
// We considered encoding whether an asset is fungible/non-fungible in erc1155 assetData, but
|
||||
// this is no more robust than a simple check by the client. Enforcing this at the smart contract level
|
||||
// is something that could be done with the upcoming static call proxy.
|
||||
//
|
||||
// setup test parameters
|
||||
// the maker is trading two fungibles and the taker is trading one fungible
|
||||
// note that this will result in a partial fill because the `takerAssetAmount`
|
||||
// less than the `takerAssetAmount` of the order.
|
||||
const takerAssetFillAmount = new BigNumber(6);
|
||||
const tokenHolders = [makerAddress, takerAddress];
|
||||
const makerAssetsToTransfer = erc1155FungibleTokens.slice(0, 2);
|
||||
const takerAssetsToTransfer = erc1155FungibleTokens.slice(2, 3);
|
||||
const makerValuesToTransfer = [new BigNumber(500), new BigNumber(700)];
|
||||
const takerValuesToTransfer = [new BigNumber(900)];
|
||||
const tokensToTransfer = makerAssetsToTransfer.concat(takerAssetsToTransfer);
|
||||
const makerAssetAmount = new BigNumber(10);
|
||||
const takerAssetAmount = new BigNumber(20);
|
||||
const totalMakerValuesTransferred = _.map(makerValuesToTransfer, (value: BigNumber) => {
|
||||
return value
|
||||
.times(makerAssetAmount)
|
||||
.times(takerAssetFillAmount)
|
||||
.dividedToIntegerBy(takerAssetAmount);
|
||||
});
|
||||
const totalTakerValuesTransferred = _.map(takerValuesToTransfer, (value: BigNumber) => {
|
||||
return value
|
||||
.times(takerAssetAmount)
|
||||
.times(takerAssetFillAmount)
|
||||
.dividedToIntegerBy(takerAssetAmount);
|
||||
});
|
||||
const receiverCallbackData = '0x';
|
||||
const makerAssetData = assetDataUtils.encodeERC1155AssetData(
|
||||
erc1155Contract.address,
|
||||
makerAssetsToTransfer,
|
||||
makerValuesToTransfer,
|
||||
receiverCallbackData,
|
||||
);
|
||||
const takerAssetData = assetDataUtils.encodeERC1155AssetData(
|
||||
erc1155Contract.address,
|
||||
takerAssetsToTransfer,
|
||||
takerValuesToTransfer,
|
||||
receiverCallbackData,
|
||||
);
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetData,
|
||||
takerAssetData,
|
||||
makerAssetAmount,
|
||||
takerAssetAmount,
|
||||
makerFee: constants.ZERO_AMOUNT,
|
||||
takerFee: constants.ZERO_AMOUNT,
|
||||
});
|
||||
// check balances before transfer
|
||||
const expectedInitialBalances = [
|
||||
// makerAddress / makerToken[0]
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// makerAddress / makerToken[1]
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// makerAddress / takerToken[0]
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// takerAddress / makerToken[0]
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// takerAddress / makerToken[1]
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
// takerAddress / takerToken[0]
|
||||
constants.INITIAL_ERC1155_FUNGIBLE_BALANCE,
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances);
|
||||
// execute transfer
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
||||
takerAssetFillAmount,
|
||||
});
|
||||
// check balances after transfer
|
||||
const expectedFinalBalances = [
|
||||
// makerAddress / makerToken[0]
|
||||
expectedInitialBalances[0].minus(totalMakerValuesTransferred[0]),
|
||||
// makerAddress / makerToken[1]
|
||||
expectedInitialBalances[1].minus(totalMakerValuesTransferred[1]),
|
||||
// makerAddress / takerToken[0]
|
||||
expectedInitialBalances[2].plus(totalTakerValuesTransferred[0]),
|
||||
// takerAddress / makerToken[0]
|
||||
expectedInitialBalances[3].plus(totalMakerValuesTransferred[0]),
|
||||
// takerAddress / makerToken[1]
|
||||
expectedInitialBalances[4].plus(totalMakerValuesTransferred[1]),
|
||||
// takerAddress / takerToken[0]
|
||||
expectedInitialBalances[5].minus(totalTakerValuesTransferred[0]),
|
||||
];
|
||||
await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedFinalBalances);
|
||||
// check that the order is partially filled
|
||||
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = takerAssetFillAmount;
|
||||
const expectedOrderStatus = OrderStatus.Fillable;
|
||||
expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
|
||||
expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
|
||||
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOrderInfo', () => {
|
||||
beforeEach(async () => {
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { artifacts as erc1155Artifacts } from '@0x/contracts-erc1155';
|
||||
import { artifacts as erc20Artifacts } from '@0x/contracts-erc20';
|
||||
import { artifacts as erc721Artifacts } from '@0x/contracts-erc721';
|
||||
import {
|
||||
@ -25,7 +26,12 @@ export class ExchangeWrapper {
|
||||
constructor(exchangeContract: ExchangeContract, provider: Web3ProviderEngine | ZeroExProvider) {
|
||||
this._exchange = exchangeContract;
|
||||
this._web3Wrapper = new Web3Wrapper(provider);
|
||||
this._logDecoder = new LogDecoder(this._web3Wrapper, { ...artifacts, ...erc20Artifacts, ...erc721Artifacts });
|
||||
this._logDecoder = new LogDecoder(this._web3Wrapper, {
|
||||
...artifacts,
|
||||
...erc20Artifacts,
|
||||
...erc721Artifacts,
|
||||
...erc1155Artifacts,
|
||||
});
|
||||
}
|
||||
public async fillOrderAsync(
|
||||
signedOrder: SignedOrder,
|
||||
|
@ -2,10 +2,6 @@
|
||||
{
|
||||
"version": "3.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Set evmVersion to byzantium",
|
||||
"pr": 1678
|
||||
},
|
||||
{
|
||||
"note": "Do not reexport external dependencies",
|
||||
"pr": 1682
|
||||
|
@ -4,7 +4,7 @@
|
||||
"useDockerisedSolc": true,
|
||||
"isOfflineMode": false,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "byzantium",
|
||||
"evmVersion": "constantinople",
|
||||
"optimizer": {
|
||||
"enabled": true,
|
||||
"runs": 1000000,
|
||||
|
@ -2,10 +2,6 @@
|
||||
{
|
||||
"version": "3.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Set evmVersion to byzantium",
|
||||
"pr": 1678
|
||||
},
|
||||
{
|
||||
"note": "Do not reexport external dependencies",
|
||||
"pr": 1682
|
||||
|
@ -4,7 +4,7 @@
|
||||
"useDockerisedSolc": true,
|
||||
"isOfflineMode": false,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "byzantium",
|
||||
"evmVersion": "constantinople",
|
||||
"optimizer": {
|
||||
"enabled": true,
|
||||
"runs": 1000000,
|
||||
|
@ -38,7 +38,7 @@ export const constants = {
|
||||
NUM_DUMMY_ERC20_TO_DEPLOY: 3,
|
||||
NUM_DUMMY_ERC721_TO_DEPLOY: 2,
|
||||
NUM_ERC721_TOKENS_TO_MINT: 2,
|
||||
NUM_DUMMY_ERC1155_CONTRACTS_TO_DEPLOY: 1,
|
||||
NUM_DUMMY_ERC1155_CONTRACTS_TO_DEPLOY: 2,
|
||||
NUM_ERC1155_FUNGIBLE_TOKENS_MINT: 3,
|
||||
NUM_ERC1155_NONFUNGIBLE_TOKENS_MINT: 3,
|
||||
NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
|
||||
|
@ -2,10 +2,6 @@
|
||||
{
|
||||
"version": "3.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Set evmVersion to byzantium",
|
||||
"pr": 1678
|
||||
},
|
||||
{
|
||||
"note": "Optimize loops in LibAddressArray",
|
||||
"pr": 1668
|
||||
|
@ -4,7 +4,7 @@
|
||||
"useDockerisedSolc": true,
|
||||
"isOfflineMode": false,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "byzantium",
|
||||
"evmVersion": "constantinople",
|
||||
"optimizer": {
|
||||
"enabled": true,
|
||||
"runs": 1000000,
|
||||
|
@ -5,6 +5,10 @@
|
||||
{
|
||||
"note": "Add addresses for coordinator extension contract and coordinator registry",
|
||||
"pr": 1689
|
||||
},
|
||||
{
|
||||
"note": "Added Dutch Auction mainnet address",
|
||||
"pr": 1715
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -34,8 +34,7 @@ const networkToAddresses: { [networkId: number]: ContractAddresses } = {
|
||||
assetProxyOwner: '0x17992e4ffb22730138e4b62aaa6367fa9d3699a6',
|
||||
forwarder: '0x5468a1dc173652ee28d249c271fa9933144746b1',
|
||||
orderValidator: '0x9463e518dea6810309563c81d5266c1b1d149138',
|
||||
// @todo hysz/dekz: Add mainnet address once deployed.
|
||||
dutchAuction: NULL_ADDRESS,
|
||||
dutchAuction: '0x07b32a653754945666cfca91168bb207323dfe67',
|
||||
coordinatorRegistry: '0x45797531b873fd5e519477a070a955764c1a5b07',
|
||||
coordinator: '0x24675738816c87ad37e712cc24f309a0c906187f',
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as chai from 'chai';
|
||||
|
||||
import { AssetProxyId, ERC721AssetData } from '@0x/types';
|
||||
import { AssetProxyId, ERC1155AssetData, ERC721AssetData } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
|
||||
import { assetDataUtils } from '../src/asset_data_utils';
|
||||
@ -30,10 +30,14 @@ const KNOWN_ERC1155_ENCODING = {
|
||||
'0x9645780d0000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000003e90000000000000000000000000000000000000000000000000000000000002711000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000007d10000000000000000000000000000000000000000000000000000000000004e210000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000',
|
||||
};
|
||||
const KNOWN_MULTI_ASSET_ENCODING = {
|
||||
amounts: [new BigNumber(1), new BigNumber(1)],
|
||||
nestedAssetData: [KNOWN_ERC20_ENCODING.assetData, KNOWN_ERC721_ENCODING.assetData],
|
||||
amounts: [new BigNumber(70), new BigNumber(1), new BigNumber(18)],
|
||||
nestedAssetData: [
|
||||
KNOWN_ERC20_ENCODING.assetData,
|
||||
KNOWN_ERC721_ENCODING.assetData,
|
||||
KNOWN_ERC1155_ENCODING.assetData,
|
||||
],
|
||||
assetData:
|
||||
'0x94cfcdd7000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000024f47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000',
|
||||
'0x94cfcdd7000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000024f47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c4800000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002049645780d0000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000003e90000000000000000000000000000000000000000000000000000000000002711000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000007d10000000000000000000000000000000000000000000000000000000000004e210000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c4800000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
|
||||
};
|
||||
|
||||
describe('assetDataUtils', () => {
|
||||
@ -76,14 +80,14 @@ describe('assetDataUtils', () => {
|
||||
expect(decodedAssetData.tokenIds).to.be.deep.equal(KNOWN_ERC1155_ENCODING.tokenIds);
|
||||
expect(decodedAssetData.callbackData).to.be.equal(KNOWN_ERC1155_ENCODING.callbackData);
|
||||
});
|
||||
it('should encode ERC20 and ERC721 multiAssetData', () => {
|
||||
it('should encode ERC20, ERC721 and ERC1155 multiAssetData', () => {
|
||||
const assetData = assetDataUtils.encodeMultiAssetData(
|
||||
KNOWN_MULTI_ASSET_ENCODING.amounts,
|
||||
KNOWN_MULTI_ASSET_ENCODING.nestedAssetData,
|
||||
);
|
||||
expect(assetData).to.equal(KNOWN_MULTI_ASSET_ENCODING.assetData);
|
||||
});
|
||||
it('should decode ERC20 and ERC721 multiAssetData', () => {
|
||||
it('should decode ERC20, ERC721 and ERC1155 multiAssetData', () => {
|
||||
const decodedAssetData = assetDataUtils.decodeMultiAssetData(KNOWN_MULTI_ASSET_ENCODING.assetData);
|
||||
expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.MultiAsset);
|
||||
expect(decodedAssetData.amounts).to.deep.equal(KNOWN_MULTI_ASSET_ENCODING.amounts);
|
||||
@ -93,44 +97,79 @@ describe('assetDataUtils', () => {
|
||||
const decodedAssetData = assetDataUtils.decodeMultiAssetDataRecursively(KNOWN_MULTI_ASSET_ENCODING.assetData);
|
||||
expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.MultiAsset);
|
||||
expect(decodedAssetData.amounts).to.deep.equal(KNOWN_MULTI_ASSET_ENCODING.amounts);
|
||||
expect(decodedAssetData.nestedAssetData.length).to.equal(3);
|
||||
const decodedErc20AssetData = decodedAssetData.nestedAssetData[0];
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
const decodedErc721AssetData = decodedAssetData.nestedAssetData[1] as ERC721AssetData;
|
||||
expect(decodedErc20AssetData.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address);
|
||||
expect(decodedErc20AssetData.assetProxyId).to.equal(AssetProxyId.ERC20);
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
const decodedErc721AssetData = decodedAssetData.nestedAssetData[1] as ERC721AssetData;
|
||||
expect(decodedErc721AssetData.tokenAddress).to.equal(KNOWN_ERC721_ENCODING.address);
|
||||
expect(decodedErc721AssetData.assetProxyId).to.equal(AssetProxyId.ERC721);
|
||||
expect(decodedErc721AssetData.tokenId).to.be.bignumber.equal(KNOWN_ERC721_ENCODING.tokenId);
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
const decodedErc1155AssetData = decodedAssetData.nestedAssetData[2] as ERC1155AssetData;
|
||||
expect(decodedErc1155AssetData.tokenAddress).to.be.equal(KNOWN_ERC1155_ENCODING.tokenAddress);
|
||||
expect(decodedErc1155AssetData.tokenValues).to.be.deep.equal(KNOWN_ERC1155_ENCODING.tokenValues);
|
||||
expect(decodedErc1155AssetData.tokenIds).to.be.deep.equal(KNOWN_ERC1155_ENCODING.tokenIds);
|
||||
expect(decodedErc1155AssetData.callbackData).to.be.equal(KNOWN_ERC1155_ENCODING.callbackData);
|
||||
});
|
||||
it('should recursively decode nested assetData within multiAssetData', () => {
|
||||
const amounts = [new BigNumber(1), new BigNumber(1), new BigNumber(2)];
|
||||
// setup test parameters
|
||||
const erc20Amount = new BigNumber(1);
|
||||
const erc721Amount = new BigNumber(1);
|
||||
const erc1155Amount = new BigNumber(15);
|
||||
const nestedAssetsAmount = new BigNumber(2);
|
||||
const amounts = [erc20Amount, erc721Amount, erc1155Amount, nestedAssetsAmount];
|
||||
const nestedAssetData = [
|
||||
KNOWN_ERC20_ENCODING.assetData,
|
||||
KNOWN_ERC721_ENCODING.assetData,
|
||||
KNOWN_ERC1155_ENCODING.assetData,
|
||||
KNOWN_MULTI_ASSET_ENCODING.assetData,
|
||||
];
|
||||
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
|
||||
// execute test
|
||||
const decodedAssetData = assetDataUtils.decodeMultiAssetDataRecursively(assetData);
|
||||
// validate asset data
|
||||
expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.MultiAsset);
|
||||
const expectedAmounts = [new BigNumber(1), new BigNumber(1), new BigNumber(2), new BigNumber(2)];
|
||||
const expectedAmounts = [
|
||||
erc20Amount,
|
||||
erc721Amount,
|
||||
erc1155Amount,
|
||||
KNOWN_MULTI_ASSET_ENCODING.amounts[0].times(nestedAssetsAmount),
|
||||
KNOWN_MULTI_ASSET_ENCODING.amounts[1].times(nestedAssetsAmount),
|
||||
KNOWN_MULTI_ASSET_ENCODING.amounts[2].times(nestedAssetsAmount),
|
||||
];
|
||||
expect(decodedAssetData.amounts).to.deep.equal(expectedAmounts);
|
||||
const expectedLength = 4;
|
||||
expect(decodedAssetData.nestedAssetData.length).to.be.equal(expectedLength);
|
||||
const decodedErc20AssetData1 = decodedAssetData.nestedAssetData[0];
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
const decodedErc721AssetData1 = decodedAssetData.nestedAssetData[1] as ERC721AssetData;
|
||||
const decodedErc20AssetData2 = decodedAssetData.nestedAssetData[2];
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
const decodedErc721AssetData2 = decodedAssetData.nestedAssetData[3] as ERC721AssetData;
|
||||
const expectedNestedAssetDataLength = 6;
|
||||
expect(decodedAssetData.nestedAssetData.length).to.be.equal(expectedNestedAssetDataLength);
|
||||
// validate nested asset data (outer)
|
||||
let nestedAssetDataIndex = 0;
|
||||
const decodedErc20AssetData1 = decodedAssetData.nestedAssetData[nestedAssetDataIndex++];
|
||||
expect(decodedErc20AssetData1.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address);
|
||||
expect(decodedErc20AssetData1.assetProxyId).to.equal(AssetProxyId.ERC20);
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
const decodedErc721AssetData1 = decodedAssetData.nestedAssetData[nestedAssetDataIndex++] as ERC721AssetData;
|
||||
expect(decodedErc721AssetData1.tokenAddress).to.equal(KNOWN_ERC721_ENCODING.address);
|
||||
expect(decodedErc721AssetData1.assetProxyId).to.equal(AssetProxyId.ERC721);
|
||||
expect(decodedErc721AssetData1.tokenId).to.be.bignumber.equal(KNOWN_ERC721_ENCODING.tokenId);
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
const decodedErc1155AssetData1 = decodedAssetData.nestedAssetData[nestedAssetDataIndex++] as ERC1155AssetData;
|
||||
expect(decodedErc1155AssetData1.tokenAddress).to.be.equal(KNOWN_ERC1155_ENCODING.tokenAddress);
|
||||
expect(decodedErc1155AssetData1.tokenValues).to.be.deep.equal(KNOWN_ERC1155_ENCODING.tokenValues);
|
||||
expect(decodedErc1155AssetData1.tokenIds).to.be.deep.equal(KNOWN_ERC1155_ENCODING.tokenIds);
|
||||
expect(decodedErc1155AssetData1.callbackData).to.be.equal(KNOWN_ERC1155_ENCODING.callbackData);
|
||||
// validate nested asset data (inner)
|
||||
const decodedErc20AssetData2 = decodedAssetData.nestedAssetData[nestedAssetDataIndex++];
|
||||
expect(decodedErc20AssetData2.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address);
|
||||
expect(decodedErc20AssetData2.assetProxyId).to.equal(AssetProxyId.ERC20);
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
const decodedErc721AssetData2 = decodedAssetData.nestedAssetData[nestedAssetDataIndex++] as ERC721AssetData;
|
||||
expect(decodedErc721AssetData2.tokenAddress).to.equal(KNOWN_ERC721_ENCODING.address);
|
||||
expect(decodedErc721AssetData2.assetProxyId).to.equal(AssetProxyId.ERC721);
|
||||
expect(decodedErc721AssetData2.tokenId).to.be.bignumber.equal(KNOWN_ERC721_ENCODING.tokenId);
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
const decodedErc1155AssetData2 = decodedAssetData.nestedAssetData[nestedAssetDataIndex++] as ERC1155AssetData;
|
||||
expect(decodedErc1155AssetData2.tokenAddress).to.be.equal(KNOWN_ERC1155_ENCODING.tokenAddress);
|
||||
expect(decodedErc1155AssetData2.tokenValues).to.be.deep.equal(KNOWN_ERC1155_ENCODING.tokenValues);
|
||||
expect(decodedErc1155AssetData2.tokenIds).to.be.deep.equal(KNOWN_ERC1155_ENCODING.tokenIds);
|
||||
expect(decodedErc1155AssetData2.callbackData).to.be.equal(KNOWN_ERC1155_ENCODING.callbackData);
|
||||
});
|
||||
});
|
||||
|
@ -9,6 +9,10 @@
|
||||
{
|
||||
"note": "Fix issue where ERC721 Approval events could cause a lookup on undefined object",
|
||||
"pr": 1692
|
||||
},
|
||||
{
|
||||
"note": "Fix race-condition bugs due to async event callbacks modifying shared state",
|
||||
"pr": 1718
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -81,6 +81,7 @@
|
||||
"ethereumjs-blockstream": "6.0.0",
|
||||
"ethers": "~4.0.4",
|
||||
"lodash": "^4.17.11",
|
||||
"semaphore-async-await": "^1.5.1",
|
||||
"websocket": "^1.0.26"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
@ -42,6 +42,7 @@ import {
|
||||
ZeroExProvider,
|
||||
} from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
import { Lock } from 'semaphore-async-await';
|
||||
|
||||
import { orderWatcherPartialConfigSchema } from '../schemas/order_watcher_partial_config_schema';
|
||||
import { OnOrderStateChangeCallback, OrderWatcherConfig, OrderWatcherError } from '../types';
|
||||
@ -84,6 +85,7 @@ export class OrderWatcher {
|
||||
private readonly _dependentOrderHashesTracker: DependentOrderHashesTracker;
|
||||
private readonly _orderStateByOrderHashCache: OrderStateByOrderHash = {};
|
||||
private readonly _orderByOrderHash: OrderByOrderHash = {};
|
||||
private readonly _lock = new Lock();
|
||||
private readonly _eventWatcher: EventWatcher;
|
||||
private readonly _provider: ZeroExProvider;
|
||||
private readonly _collisionResistantAbiDecoder: CollisionResistanceAbiDecoder;
|
||||
@ -196,10 +198,12 @@ export class OrderWatcher {
|
||||
throw new Error(OrderWatcherError.SubscriptionAlreadyPresent);
|
||||
}
|
||||
this._callbackIfExists = callback;
|
||||
this._eventWatcher.subscribe(this._onEventWatcherCallbackAsync.bind(this));
|
||||
this._expirationWatcher.subscribe(this._onOrderExpired.bind(this));
|
||||
this._eventWatcher.subscribe(
|
||||
this._addLockToCallbackAsync.bind(this, this._onEventWatcherCallbackAsync.bind(this)),
|
||||
);
|
||||
this._expirationWatcher.subscribe(this._addLockToCallbackAsync.bind(this, this._onOrderExpired.bind(this)));
|
||||
this._cleanupJobIntervalIdIfExists = intervalUtils.setAsyncExcludingInterval(
|
||||
this._cleanupAsync.bind(this),
|
||||
this._addLockToCallbackAsync.bind(this, this._cleanupAsync.bind(this)),
|
||||
this._cleanupJobInterval,
|
||||
(err: Error) => {
|
||||
this.unsubscribe();
|
||||
@ -229,6 +233,17 @@ export class OrderWatcher {
|
||||
orderCount: _.size(this._orderByOrderHash),
|
||||
};
|
||||
}
|
||||
private async _addLockToCallbackAsync(cbAsync: any, ...params: any[]): Promise<void> {
|
||||
await this._lock.acquire();
|
||||
try {
|
||||
await cbAsync(...params);
|
||||
await this._lock.release();
|
||||
} catch (err) {
|
||||
// Make sure to releasee the lock if an error is thrown
|
||||
await this._lock.release();
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
private async _cleanupAsync(): Promise<void> {
|
||||
for (const orderHash of _.keys(this._orderByOrderHash)) {
|
||||
this._cleanupOrderRelatedState(orderHash);
|
||||
@ -493,4 +508,4 @@ export class OrderWatcher {
|
||||
this._callbackIfExists(null, orderState);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // tslint:disable:max-file-line-count
|
||||
|
@ -175,10 +175,14 @@ describe('OrderWatcher', () => {
|
||||
});
|
||||
});
|
||||
describe('tests with cleanup', async () => {
|
||||
beforeEach(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
});
|
||||
afterEach(async () => {
|
||||
orderWatcher.unsubscribe();
|
||||
const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
orderWatcher.removeOrder(orderHash);
|
||||
await blockchainLifecycle.revertAsync();
|
||||
});
|
||||
it('should emit orderStateInvalid when makerAddress allowance set to 0 for watched order', (done: DoneCallback) => {
|
||||
(async () => {
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"version": "4.0.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Update ganache-core to 2.5.3",
|
||||
"pr": 1707
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1551479279,
|
||||
"version": "4.0.2",
|
||||
|
@ -45,7 +45,7 @@
|
||||
"ethereum-types": "^2.1.0",
|
||||
"ethereumjs-tx": "^1.3.5",
|
||||
"ethereumjs-util": "^5.1.1",
|
||||
"ganache-core": "^2.3.3",
|
||||
"ganache-core": "^2.5.3",
|
||||
"hdkey": "^0.7.1",
|
||||
"json-rpc-error": "2.0.0",
|
||||
"lodash": "^4.17.11",
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"version": "6.0.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Update ganache-core to 2.5.3",
|
||||
"pr": 1707
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1551479279,
|
||||
"version": "6.0.2",
|
||||
|
@ -42,7 +42,7 @@
|
||||
"chai-as-promised": "^7.1.0",
|
||||
"chai-bignumber": "^3.0.0",
|
||||
"dirty-chai": "^2.0.1",
|
||||
"ganache-core": "^2.3.3",
|
||||
"ganache-core": "^2.5.3",
|
||||
"make-promises-safe": "^1.1.0",
|
||||
"mocha": "^4.1.0",
|
||||
"npm-run-all": "^4.1.2",
|
||||
|
@ -35,7 +35,7 @@ describe('Web3Wrapper tests', () => {
|
||||
describe('#getNodeVersionAsync', () => {
|
||||
it('gets the node version', async () => {
|
||||
const nodeVersion = await web3Wrapper.getNodeVersionAsync();
|
||||
const NODE_VERSION = 'EthereumJS TestRPC/v2.3.3/ethereum-js';
|
||||
const NODE_VERSION = 'EthereumJS TestRPC/v2.5.3/ethereum-js';
|
||||
expect(nodeVersion).to.be.equal(NODE_VERSION);
|
||||
});
|
||||
});
|
||||
|
@ -8,10 +8,10 @@ In order to use `CoverageSubprovider` with your favorite framework you need to p
|
||||
|
||||
### Sol-compiler
|
||||
|
||||
If you are generating your artifacts with [@0x/sol-compiler](https://0x.org/docs/sol-compiler) you can use the `SolCompilerArtifactsAdapter` we've implemented for you.
|
||||
If you are generating your artifacts with [@0x/sol-compiler](https://0x.org/docs/sol-compiler) you can use the `SolCompilerArtifactAdapter` we've implemented for you.
|
||||
|
||||
```typescript
|
||||
import { SolCompilerArtifactsAdapter } from '@0x/sol-coverage';
|
||||
import { SolCompilerArtifactAdapter } from '@0x/sol-coverage';
|
||||
// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in
|
||||
const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDir);
|
||||
```
|
||||
|
@ -8,10 +8,10 @@ In order to use `ProfilerSubprovider` with your favorite framework you need to p
|
||||
|
||||
### Sol-compiler
|
||||
|
||||
If you are generating your artifacts with [@0x/sol-compiler](https://0x.org/docs/sol-compiler) you can use the `SolCompilerArtifactsAdapter` we've implemented for you.
|
||||
If you are generating your artifacts with [@0x/sol-compiler](https://0x.org/docs/sol-compiler) you can use the `SolCompilerArtifactAdapter` we've implemented for you.
|
||||
|
||||
```typescript
|
||||
import { SolCompilerArtifactsAdapter } from '@0x/sol-profiler';
|
||||
import { SolCompilerArtifactAdapter } from '@0x/sol-profiler';
|
||||
// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in
|
||||
const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDir);
|
||||
```
|
||||
|
@ -8,10 +8,10 @@ In order to use `RevertTraceSubprovider` with your favorite framework you need t
|
||||
|
||||
### Sol-compiler
|
||||
|
||||
If you are generating your artifacts with [@0x/sol-compiler](https://0x.org/docs/sol-compiler) you can use the `SolCompilerArtifactsAdapter` we've implemented for you.
|
||||
If you are generating your artifacts with [@0x/sol-compiler](https://0x.org/docs/sol-compiler) you can use the `SolCompilerArtifactAdapter` we've implemented for you.
|
||||
|
||||
```typescript
|
||||
import { SolCompilerArtifactsAdapter } from '@0x/sol-trace';
|
||||
import { SolCompilerArtifactAdapter } from '@0x/sol-trace';
|
||||
// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in
|
||||
const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDir);
|
||||
```
|
||||
|
BIN
packages/website/public/images/team/danielp.png
Normal file
BIN
packages/website/public/images/team/danielp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 85 KiB |
@ -158,6 +158,11 @@ const team: TeamMember[] = [
|
||||
name: 'Marc Savino',
|
||||
title: 'technical sourcer',
|
||||
},
|
||||
{
|
||||
imageUrl: '/images/team/danielp.png',
|
||||
name: 'Daniel Pyrathon',
|
||||
title: 'engineer',
|
||||
},
|
||||
];
|
||||
|
||||
const advisors: TeamMember[] = [
|
||||
|
123
yarn.lock
123
yarn.lock
@ -6495,6 +6495,16 @@ ethereumjs-block@^1.2.2, ethereumjs-block@^1.4.1, ethereumjs-block@^1.6.0, ether
|
||||
ethereumjs-util "^5.0.0"
|
||||
merkle-patricia-tree "^2.1.2"
|
||||
|
||||
ethereumjs-block@~2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-2.2.0.tgz#8c6c3ab4a5eff0a16d9785fbeedbe643f4dbcbef"
|
||||
dependencies:
|
||||
async "^2.0.1"
|
||||
ethereumjs-common "^1.1.0"
|
||||
ethereumjs-tx "^1.2.2"
|
||||
ethereumjs-util "^5.0.0"
|
||||
merkle-patricia-tree "^2.1.2"
|
||||
|
||||
ethereumjs-blockstream@6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ethereumjs-blockstream/-/ethereumjs-blockstream-6.0.0.tgz#79d726d1f358935eb65195e91d40344c31e87eff"
|
||||
@ -6507,9 +6517,9 @@ ethereumjs-common@^0.6.0:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-0.6.1.tgz#ec98edf315a7f107afb6acc48e937a8266979fae"
|
||||
|
||||
ethereumjs-common@~0.4.0:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-0.4.1.tgz#27690a24a817b058cc3a2aedef9392e8d7d63984"
|
||||
ethereumjs-common@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.1.0.tgz#5ec9086c314d619d8f05e79a0525829fcb0e93cb"
|
||||
|
||||
ethereumjs-tx@1.3.7:
|
||||
version "1.3.7"
|
||||
@ -6559,21 +6569,17 @@ ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereum
|
||||
safe-buffer "^5.1.1"
|
||||
secp256k1 "^3.0.1"
|
||||
|
||||
ethereumjs-vm@2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.4.0.tgz#244f1e35f2755e537a13546111d1a4c159d34b13"
|
||||
ethereumjs-util@^6.0.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.1.0.tgz#e9c51e5549e8ebd757a339cc00f5380507e799c8"
|
||||
dependencies:
|
||||
async "^2.1.2"
|
||||
async-eventemitter "^0.2.2"
|
||||
ethereumjs-account "^2.0.3"
|
||||
ethereumjs-block "~1.7.0"
|
||||
ethereumjs-common "~0.4.0"
|
||||
ethereumjs-util "^5.2.0"
|
||||
fake-merkle-patricia-tree "^1.0.1"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
merkle-patricia-tree "^2.1.2"
|
||||
rustbn.js "~0.2.0"
|
||||
bn.js "^4.11.0"
|
||||
create-hash "^1.1.2"
|
||||
ethjs-util "0.1.6"
|
||||
keccak "^1.0.2"
|
||||
rlp "^2.0.0"
|
||||
safe-buffer "^5.1.1"
|
||||
secp256k1 "^3.0.1"
|
||||
|
||||
ethereumjs-vm@^2.0.2, ethereumjs-vm@^2.1.0, ethereumjs-vm@^2.3.4:
|
||||
version "2.3.4"
|
||||
@ -6591,6 +6597,22 @@ ethereumjs-vm@^2.0.2, ethereumjs-vm@^2.1.0, ethereumjs-vm@^2.3.4:
|
||||
rustbn.js "~0.1.1"
|
||||
safe-buffer "^5.1.1"
|
||||
|
||||
ethereumjs-vm@^2.6.0:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz#76243ed8de031b408793ac33907fb3407fe400c6"
|
||||
dependencies:
|
||||
async "^2.1.2"
|
||||
async-eventemitter "^0.2.2"
|
||||
ethereumjs-account "^2.0.3"
|
||||
ethereumjs-block "~2.2.0"
|
||||
ethereumjs-common "^1.1.0"
|
||||
ethereumjs-util "^6.0.0"
|
||||
fake-merkle-patricia-tree "^1.0.1"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
merkle-patricia-tree "^2.3.2"
|
||||
rustbn.js "~0.2.0"
|
||||
safe-buffer "^5.1.1"
|
||||
|
||||
ethereumjs-wallet@0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.2.tgz#67244b6af3e8113b53d709124b25477b64aeccda"
|
||||
@ -6642,6 +6664,13 @@ ethjs-unit@0.1.6:
|
||||
bn.js "4.11.6"
|
||||
number-to-bn "1.7.0"
|
||||
|
||||
ethjs-util@0.1.6:
|
||||
version "0.1.6"
|
||||
resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536"
|
||||
dependencies:
|
||||
is-hex-prefixed "1.0.0"
|
||||
strip-hex-prefix "1.0.0"
|
||||
|
||||
ethjs-util@^0.1.3:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.4.tgz#1c8b6879257444ef4d3f3fbbac2ded12cd997d93"
|
||||
@ -7506,9 +7535,9 @@ ganache-cli@6.4.1:
|
||||
source-map-support "0.5.9"
|
||||
yargs "11.1.0"
|
||||
|
||||
ganache-core@^2.3.3:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/ganache-core/-/ganache-core-2.3.3.tgz#e35c76d405f0ffba5c48621596fdcc38b0a03136"
|
||||
ganache-core@^2.5.3:
|
||||
version "2.5.3"
|
||||
resolved "https://registry.yarnpkg.com/ganache-core/-/ganache-core-2.5.3.tgz#8c6f21d820a694826082dfbb2dc59f834a6874fc"
|
||||
dependencies:
|
||||
abstract-leveldown "3.0.0"
|
||||
async "2.6.1"
|
||||
@ -7524,11 +7553,11 @@ ganache-core@^2.3.3:
|
||||
ethereumjs-block "2.1.0"
|
||||
ethereumjs-tx "1.3.7"
|
||||
ethereumjs-util "5.2.0"
|
||||
ethereumjs-vm "2.4.0"
|
||||
ethereumjs-vm "^2.6.0"
|
||||
heap "0.2.6"
|
||||
level-sublevel "6.6.4"
|
||||
levelup "3.1.1"
|
||||
lodash "4.17.10"
|
||||
lodash "4.17.11"
|
||||
merkle-patricia-tree "2.3.1"
|
||||
rlp "2.1.0"
|
||||
seedrandom "2.4.4"
|
||||
@ -10627,9 +10656,9 @@ lodash.words@^3.0.0:
|
||||
dependencies:
|
||||
lodash._root "^3.0.0"
|
||||
|
||||
lodash@4.17.10, lodash@^4.17.10:
|
||||
version "4.17.10"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
|
||||
lodash@4.17.11, lodash@^4.0.0, lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.11, lodash@^4.17.3:
|
||||
version "4.17.11"
|
||||
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
|
||||
|
||||
lodash@=4.17.4:
|
||||
version "4.17.4"
|
||||
@ -10639,14 +10668,14 @@ lodash@^3.3.1, lodash@^3.6.0, lodash@^3.7.0:
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
|
||||
|
||||
lodash@^4.0.0, lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.11, lodash@^4.17.3:
|
||||
version "4.17.11"
|
||||
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
|
||||
|
||||
lodash@^4.14.0, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.1:
|
||||
version "4.17.5"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"
|
||||
|
||||
lodash@^4.17.10:
|
||||
version "4.17.10"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
|
||||
|
||||
lodash@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551"
|
||||
@ -11046,6 +11075,19 @@ merkle-patricia-tree@2.3.1, merkle-patricia-tree@^2.1.2:
|
||||
rlp "^2.0.0"
|
||||
semaphore ">=1.0.1"
|
||||
|
||||
merkle-patricia-tree@^2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz#982ca1b5a0fde00eed2f6aeed1f9152860b8208a"
|
||||
dependencies:
|
||||
async "^1.4.2"
|
||||
ethereumjs-util "^5.0.0"
|
||||
level-ws "0.0.0"
|
||||
levelup "^1.2.1"
|
||||
memdown "^1.0.0"
|
||||
readable-stream "^2.0.0"
|
||||
rlp "^2.0.0"
|
||||
semaphore ">=1.0.1"
|
||||
|
||||
methods@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
|
||||
@ -13506,6 +13548,15 @@ react-dom@^16.3.2:
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.0"
|
||||
|
||||
react-dom@^16.4.2:
|
||||
version "16.8.4"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.4.tgz#1061a8e01a2b3b0c8160037441c3bf00a0e3bc48"
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.2"
|
||||
scheduler "^0.13.4"
|
||||
|
||||
react-dom@^16.5.2:
|
||||
version "16.5.2"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.5.2.tgz#b69ee47aa20bab5327b2b9d7c1fe2a30f2cfa9d7"
|
||||
@ -13809,6 +13860,15 @@ react@^16.3.2:
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.0"
|
||||
|
||||
react@^16.4.2:
|
||||
version "16.8.4"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.8.4.tgz#fdf7bd9ae53f03a9c4cd1a371432c206be1c4768"
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.2"
|
||||
scheduler "^0.13.4"
|
||||
|
||||
react@^16.5.2:
|
||||
version "16.5.2"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.5.2.tgz#19f6b444ed139baa45609eee6dc3d318b3895d42"
|
||||
@ -14680,6 +14740,13 @@ schedule@^0.5.0:
|
||||
dependencies:
|
||||
object-assign "^4.1.1"
|
||||
|
||||
scheduler@^0.13.4:
|
||||
version "0.13.4"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.4.tgz#8fef05e7a3580c76c0364d2df5e550e4c9140298"
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
schema-utils@^0.4.4:
|
||||
version "0.4.7"
|
||||
resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187"
|
||||
|
Loading…
x
Reference in New Issue
Block a user