Add tests for transfering ERC1155 tokens out

This commit is contained in:
Amir 2020-01-13 16:35:45 -08:00
parent 350934ca21
commit 62b06cd204
5 changed files with 94 additions and 12 deletions

View File

@ -39,7 +39,7 @@
},
"config": {
"publicInterfaceContracts": "Forwarder,IExchangeV2",
"abis": "./test/generated-artifacts/@(Forwarder|IAssets|IExchangeV2|IForwarder|IForwarderCore|LibConstants|LibForwarderRichErrors|MixinAssets|MixinExchangeWrapper|MixinForwarderCore|MixinWeth|TestForwarder).json",
"abis": "./test/generated-artifacts/@(Forwarder|IAssets|IExchangeV2|IForwarder|IForwarderCore|LibAssetDataTransfer|LibConstants|LibForwarderRichErrors|MixinAssets|MixinExchangeWrapper|MixinForwarderCore|MixinReceiver|MixinWeth|TestForwarder).json",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
},
"repository": {
@ -57,6 +57,7 @@
"@0x/contracts-dev-utils": "^1.0.3",
"@0x/contracts-erc20": "^3.0.3",
"@0x/contracts-erc721": "^3.0.3",
"@0x/contracts-erc1155": "^2.0.3",
"@0x/contracts-exchange": "^3.0.3",
"@0x/contracts-exchange-libs": "^4.0.3",
"@0x/contracts-gen": "^2.0.3",

View File

@ -10,11 +10,13 @@ import * as IAssets from '../test/generated-artifacts/IAssets.json';
import * as IExchangeV2 from '../test/generated-artifacts/IExchangeV2.json';
import * as IForwarder from '../test/generated-artifacts/IForwarder.json';
import * as IForwarderCore from '../test/generated-artifacts/IForwarderCore.json';
import * as LibAssetDataTransfer from '../test/generated-artifacts/LibAssetDataTransfer.json';
import * as LibConstants from '../test/generated-artifacts/LibConstants.json';
import * as LibForwarderRichErrors from '../test/generated-artifacts/LibForwarderRichErrors.json';
import * as MixinAssets from '../test/generated-artifacts/MixinAssets.json';
import * as MixinExchangeWrapper from '../test/generated-artifacts/MixinExchangeWrapper.json';
import * as MixinForwarderCore from '../test/generated-artifacts/MixinForwarderCore.json';
import * as MixinReceiver from '../test/generated-artifacts/MixinReceiver.json';
import * as MixinWeth from '../test/generated-artifacts/MixinWeth.json';
import * as TestForwarder from '../test/generated-artifacts/TestForwarder.json';
export const artifacts = {
@ -22,11 +24,13 @@ export const artifacts = {
MixinAssets: MixinAssets as ContractArtifact,
MixinExchangeWrapper: MixinExchangeWrapper as ContractArtifact,
MixinForwarderCore: MixinForwarderCore as ContractArtifact,
MixinReceiver: MixinReceiver as ContractArtifact,
MixinWeth: MixinWeth as ContractArtifact,
IAssets: IAssets as ContractArtifact,
IExchangeV2: IExchangeV2 as ContractArtifact,
IForwarder: IForwarder as ContractArtifact,
IForwarderCore: IForwarderCore as ContractArtifact,
LibAssetDataTransfer: LibAssetDataTransfer as ContractArtifact,
LibConstants: LibConstants as ContractArtifact,
LibForwarderRichErrors: LibForwarderRichErrors as ContractArtifact,
TestForwarder: TestForwarder as ContractArtifact,

View File

@ -1,4 +1,10 @@
import { IAssetDataContract } from '@0x/contracts-asset-proxy';
import {
artifacts as ERC1155Artifacts,
ERC1155MintableContract,
ERC1155TransferBatchEventArgs,
Erc1155Wrapper,
} from '@0x/contracts-erc1155';
import {
artifacts as ERC20Artifacts,
DummyERC20TokenContract,
@ -25,6 +31,7 @@ import { LogWithDecodedArgs } from 'ethereum-types';
import { artifacts } from './artifacts';
import { TestForwarderContract } from './wrappers';
// tslint:disable:no-unnecessary-type-assertion
blockchainTests.resets('Supported asset type unit tests', env => {
let forwarder: TestForwarderContract;
let assetDataEncoder: IAssetDataContract;
@ -34,6 +41,8 @@ blockchainTests.resets('Supported asset type unit tests', env => {
let erc20Token: DummyERC20TokenContract;
let erc721Token: DummyERC721TokenContract;
let erc1155Token: ERC1155MintableContract;
let erc1155Wrapper: Erc1155Wrapper;
let nftId: BigNumber;
let erc20AssetData: string;
@ -50,7 +59,7 @@ blockchainTests.resets('Supported asset type unit tests', env => {
artifacts.TestForwarder,
env.provider,
env.txDefaults,
{ ...artifacts, ...ERC20Artifacts, ...ERC721Artifacts },
{ ...artifacts, ...ERC20Artifacts, ...ERC721Artifacts, ...ERC1155Artifacts },
);
erc20Token = await DummyERC20TokenContract.deployFrom0xArtifactAsync(
@ -76,6 +85,14 @@ blockchainTests.resets('Supported asset type unit tests', env => {
nftId = getRandomInteger(0, constants.MAX_UINT256);
erc721AssetData = assetDataEncoder.ERC721Token(erc721Token.address, nftId).getABIEncodedTransactionData();
erc1155Token = await ERC1155MintableContract.deployFrom0xArtifactAsync(
ERC1155Artifacts.ERC1155Mintable,
env.provider,
env.txDefaults,
ERC1155Artifacts,
);
erc1155Wrapper = new Erc1155Wrapper(erc1155Token, receiver);
bridgeAddress = randomAddress();
bridgeData = hexUtils.random();
erc20BridgeAssetData = assetDataEncoder
@ -183,7 +200,7 @@ blockchainTests.resets('Supported asset type unit tests', env => {
});
});
describe('_transferAssetToSender', () => {
describe('transferOut', () => {
const TRANSFER_AMOUNT = new BigNumber(1);
before(async () => {
await erc20Token
@ -194,7 +211,7 @@ blockchainTests.resets('Supported asset type unit tests', env => {
it('transfers an ERC20 token given ERC20 assetData', async () => {
const txReceipt = await forwarder
.transferAssetToSender(erc20AssetData, TRANSFER_AMOUNT)
.transferOut(erc20AssetData, TRANSFER_AMOUNT)
.awaitTransactionSuccessAsync({ from: receiver });
verifyEventsFromLogs<ERC20TokenTransferEventArgs>(
txReceipt.logs,
@ -204,7 +221,7 @@ blockchainTests.resets('Supported asset type unit tests', env => {
});
it('transfers an ERC721 token given ERC721 assetData and amount == 1', async () => {
const txReceipt = await forwarder
.transferAssetToSender(erc721AssetData, TRANSFER_AMOUNT)
.transferOut(erc721AssetData, TRANSFER_AMOUNT)
.awaitTransactionSuccessAsync({ from: receiver });
verifyEventsFromLogs<ERC721TokenTransferEventArgs>(
txReceipt.logs,
@ -215,11 +232,67 @@ blockchainTests.resets('Supported asset type unit tests', env => {
it('reverts if attempting to transfer an ERC721 token with amount != 1', async () => {
const invalidAmount = new BigNumber(2);
const tx = forwarder
.transferAssetToSender(erc721AssetData, invalidAmount)
.transferOut(erc721AssetData, invalidAmount)
.awaitTransactionSuccessAsync({ from: receiver });
const expectedError = new ExchangeForwarderRevertErrors.Erc721AmountMustEqualOneError(invalidAmount);
return expect(tx).to.revertWith(expectedError);
});
it('transfers a single ERC1155 token', async () => {
const values = [new BigNumber(1)];
const amount = new BigNumber(1);
const ids = [await erc1155Wrapper.mintFungibleTokensAsync([forwarder.address], values)];
const assetData = assetDataEncoder
.ERC1155Assets(erc1155Token.address, ids, values, constants.NULL_BYTES)
.getABIEncodedTransactionData();
const txReceipt = await forwarder
.transferOut(assetData, amount)
.awaitTransactionSuccessAsync({ from: receiver });
const logArgs = (txReceipt.logs[0] as LogWithDecodedArgs<ERC1155TransferBatchEventArgs>).args;
expect(logArgs.operator).to.eq(forwarder.address);
expect(logArgs.from).to.eq(forwarder.address);
expect(logArgs.to).to.eq(receiver);
logArgs.ids.forEach((id, i) => expect(new BigNumber(id)).to.bignumber.eq(ids[i]));
logArgs.values.forEach((value, i) => expect(new BigNumber(value)).to.bignumber.eq(values[i]));
});
it('transfers multiple ids of an ERC1155 token', async () => {
const amount = new BigNumber(1);
const ids = [
await erc1155Wrapper.mintFungibleTokensAsync([forwarder.address], [amount]),
await erc1155Wrapper.mintFungibleTokensAsync([forwarder.address], [amount]),
];
const values = [amount, amount];
const assetData = assetDataEncoder
.ERC1155Assets(erc1155Token.address, ids, values, constants.NULL_BYTES)
.getABIEncodedTransactionData();
const txReceipt = await forwarder.transferOut(assetData, amount).awaitTransactionSuccessAsync();
const logArgs = (txReceipt.logs[0] as LogWithDecodedArgs<ERC1155TransferBatchEventArgs>).args;
expect(logArgs.operator).to.eq(forwarder.address);
expect(logArgs.from).to.eq(forwarder.address);
expect(logArgs.to).to.eq(receiver);
logArgs.ids.forEach((id, i) => expect(new BigNumber(id)).to.bignumber.eq(ids[i]));
logArgs.values.forEach((value, i) => expect(new BigNumber(value)).to.bignumber.eq(values[i]));
});
it('scales up values when transfering ERC1155 tokens', async () => {
it('transfers multiple ids of an ERC1155 token', async () => {
const amount = new BigNumber(2);
const ids = [
await erc1155Wrapper.mintFungibleTokensAsync([forwarder.address], [amount]),
await erc1155Wrapper.mintFungibleTokensAsync([forwarder.address], [amount]),
];
const values = [new BigNumber(1), new BigNumber(2)];
const assetData = assetDataEncoder
.ERC1155Assets(erc1155Token.address, ids, values, constants.NULL_BYTES)
.getABIEncodedTransactionData();
const txReceipt = await forwarder.transferOut(assetData, amount).awaitTransactionSuccessAsync();
const scaledValues = values.map(value => value.times(amount));
const logArgs = (txReceipt.logs[0] as LogWithDecodedArgs<ERC1155TransferBatchEventArgs>).args;
expect(logArgs.operator).to.eq(forwarder.address);
expect(logArgs.from).to.eq(forwarder.address);
expect(logArgs.to).to.eq(receiver);
logArgs.ids.forEach((id, i) => expect(new BigNumber(id)).to.bignumber.eq(ids[i]));
logArgs.values.forEach((value, i) => expect(new BigNumber(value)).to.bignumber.eq(scaledValues[i]));
});
});
it('transfers a single ERC20 token wrapped as MultiAsset', async () => {
const nestedAmount = new BigNumber(1337);
const erc20MultiAssetData = assetDataEncoder
@ -227,7 +300,7 @@ blockchainTests.resets('Supported asset type unit tests', env => {
.getABIEncodedTransactionData();
const multiAssetAmount = new BigNumber(2);
const txReceipt = await forwarder
.transferAssetToSender(erc20MultiAssetData, multiAssetAmount)
.transferOut(erc20MultiAssetData, multiAssetAmount)
.awaitTransactionSuccessAsync({ from: receiver });
verifyEventsFromLogs<ERC20TokenTransferEventArgs>(
txReceipt.logs,
@ -241,7 +314,7 @@ blockchainTests.resets('Supported asset type unit tests', env => {
.MultiAsset(nestedAmounts, [erc20AssetData, erc721AssetData, staticCallAssetData])
.getABIEncodedTransactionData();
const txReceipt = await forwarder
.transferAssetToSender(assortedMultiAssetData, TRANSFER_AMOUNT)
.transferOut(assortedMultiAssetData, TRANSFER_AMOUNT)
.awaitTransactionSuccessAsync({ from: receiver });
expect(txReceipt.logs.length).to.equal(2);
// tslint:disable:no-unnecessary-type-assertion
@ -261,7 +334,7 @@ blockchainTests.resets('Supported asset type unit tests', env => {
.MultiAsset(nestedAmounts, [multiAssetData, erc721AssetData, staticCallAssetData])
.getABIEncodedTransactionData();
const txReceipt = await forwarder
.transferAssetToSender(assortedMultiAssetData, TRANSFER_AMOUNT)
.transferOut(assortedMultiAssetData, TRANSFER_AMOUNT)
.awaitTransactionSuccessAsync({ from: receiver });
expect(txReceipt.logs.length).to.equal(2);
// tslint:disable:no-unnecessary-type-assertion
@ -277,7 +350,7 @@ blockchainTests.resets('Supported asset type unit tests', env => {
});
it('transfers an ERC20 token given ERC20Bridge assetData', async () => {
const txReceipt = await forwarder
.transferAssetToSender(erc20BridgeAssetData, TRANSFER_AMOUNT)
.transferOut(erc20BridgeAssetData, TRANSFER_AMOUNT)
.awaitTransactionSuccessAsync({ from: receiver });
verifyEventsFromLogs<ERC20TokenTransferEventArgs>(
txReceipt.logs,
@ -287,14 +360,14 @@ blockchainTests.resets('Supported asset type unit tests', env => {
});
it('noops (emits no events) for StaticCall assetData', async () => {
const txReceipt = await forwarder
.transferAssetToSender(staticCallAssetData, TRANSFER_AMOUNT)
.transferOut(staticCallAssetData, TRANSFER_AMOUNT)
.awaitTransactionSuccessAsync({ from: receiver });
expect(txReceipt.logs.length).to.equal(0);
});
it('reverts if assetData is unsupported', async () => {
const randomBytes = hexUtils.random();
const tx = forwarder
.transferAssetToSender(randomBytes, TRANSFER_AMOUNT)
.transferOut(randomBytes, TRANSFER_AMOUNT)
.awaitTransactionSuccessAsync({ from: receiver });
const expectedError = new ExchangeForwarderRevertErrors.UnsupportedAssetProxyError(
hexUtils.slice(randomBytes, 0, 4),

View File

@ -8,10 +8,12 @@ export * from '../test/generated-wrappers/i_assets';
export * from '../test/generated-wrappers/i_exchange_v2';
export * from '../test/generated-wrappers/i_forwarder';
export * from '../test/generated-wrappers/i_forwarder_core';
export * from '../test/generated-wrappers/lib_asset_data_transfer';
export * from '../test/generated-wrappers/lib_constants';
export * from '../test/generated-wrappers/lib_forwarder_rich_errors';
export * from '../test/generated-wrappers/mixin_assets';
export * from '../test/generated-wrappers/mixin_exchange_wrapper';
export * from '../test/generated-wrappers/mixin_forwarder_core';
export * from '../test/generated-wrappers/mixin_receiver';
export * from '../test/generated-wrappers/mixin_weth';
export * from '../test/generated-wrappers/test_forwarder';

View File

@ -10,11 +10,13 @@
"test/generated-artifacts/IExchangeV2.json",
"test/generated-artifacts/IForwarder.json",
"test/generated-artifacts/IForwarderCore.json",
"test/generated-artifacts/LibAssetDataTransfer.json",
"test/generated-artifacts/LibConstants.json",
"test/generated-artifacts/LibForwarderRichErrors.json",
"test/generated-artifacts/MixinAssets.json",
"test/generated-artifacts/MixinExchangeWrapper.json",
"test/generated-artifacts/MixinForwarderCore.json",
"test/generated-artifacts/MixinReceiver.json",
"test/generated-artifacts/MixinWeth.json",
"test/generated-artifacts/TestForwarder.json"
],