Unit tests
This commit is contained in:
parent
49e898b189
commit
d51bbb0008
@ -0,0 +1,63 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../src/MixinExchangeWrapper.sol";
|
||||
import "../src/libs/LibConstants.sol";
|
||||
|
||||
|
||||
contract TestForwarder is
|
||||
LibConstants,
|
||||
MixinExchangeWrapper
|
||||
{
|
||||
// solhint-disable no-empty-blocks
|
||||
constructor ()
|
||||
public
|
||||
LibConstants(
|
||||
address(0),
|
||||
address(0)
|
||||
)
|
||||
{}
|
||||
|
||||
function isPercentageFee(
|
||||
bytes memory takerFeeAssetData,
|
||||
bytes memory makerAssetData
|
||||
)
|
||||
public
|
||||
returns (bool)
|
||||
{
|
||||
return _isPercentageFee(
|
||||
takerFeeAssetData,
|
||||
makerAssetData
|
||||
);
|
||||
}
|
||||
|
||||
function transferAssetToSender(
|
||||
bytes memory assetData,
|
||||
uint256 amount
|
||||
)
|
||||
public
|
||||
{
|
||||
_transferAssetToSender(
|
||||
assetData,
|
||||
amount
|
||||
);
|
||||
}
|
||||
}
|
@ -14,11 +14,12 @@
|
||||
"build:ts": "tsc -b",
|
||||
"build:ci": "yarn build",
|
||||
"pre_build": "run-s compile contracts:gen generate_contract_wrappers contracts:copy",
|
||||
"test": "echo !!! Tests have been relocated to @0x/contracts-integrations !!!",
|
||||
"test": "yarn run_mocha",
|
||||
"rebuild_and_test": "run-s build test",
|
||||
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
|
||||
"test:profiler": "SOLIDITY_PROFILER=true run-s build run_mocha profiler:report:html",
|
||||
"test:trace": "SOLIDITY_REVERT_TRACE=true run-s build run_mocha",
|
||||
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
|
||||
"compile": "sol-compiler",
|
||||
"watch": "sol-compiler -w",
|
||||
"clean": "shx rm -rf lib test/generated-artifacts test/generated-wrappers generated-artifacts generated-wrappers",
|
||||
@ -38,7 +39,7 @@
|
||||
},
|
||||
"config": {
|
||||
"publicInterfaceContracts": "Forwarder",
|
||||
"abis": "./test/generated-artifacts/@(Forwarder|IAssets|IForwarder|IForwarderCore|LibConstants|LibForwarderRichErrors|MixinAssets|MixinExchangeWrapper|MixinForwarderCore|MixinWeth).json",
|
||||
"abis": "./test/generated-artifacts/@(Forwarder|IAssets|IForwarder|IForwarderCore|LibConstants|LibForwarderRichErrors|MixinAssets|MixinExchangeWrapper|MixinForwarderCore|MixinWeth|TestForwarder).json",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||
},
|
||||
"repository": {
|
||||
|
@ -15,6 +15,7 @@ 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 MixinWeth from '../test/generated-artifacts/MixinWeth.json';
|
||||
import * as TestForwarder from '../test/generated-artifacts/TestForwarder.json';
|
||||
export const artifacts = {
|
||||
Forwarder: Forwarder as ContractArtifact,
|
||||
MixinAssets: MixinAssets as ContractArtifact,
|
||||
@ -26,4 +27,5 @@ export const artifacts = {
|
||||
IForwarderCore: IForwarderCore as ContractArtifact,
|
||||
LibConstants: LibConstants as ContractArtifact,
|
||||
LibForwarderRichErrors: LibForwarderRichErrors as ContractArtifact,
|
||||
TestForwarder: TestForwarder as ContractArtifact,
|
||||
};
|
||||
|
174
contracts/exchange-forwarder/test/asset_test.ts
Normal file
174
contracts/exchange-forwarder/test/asset_test.ts
Normal file
@ -0,0 +1,174 @@
|
||||
import { IAssetDataContract } from '@0x/contracts-asset-proxy';
|
||||
import {
|
||||
artifacts as ERC20Artifacts,
|
||||
DummyERC20TokenContract,
|
||||
ERC20TokenEvents,
|
||||
ERC20TokenTransferEventArgs,
|
||||
} from '@0x/contracts-erc20';
|
||||
import {
|
||||
artifacts as ERC721Artifacts,
|
||||
DummyERC721TokenContract,
|
||||
ERC721TokenEvents,
|
||||
ERC721TokenTransferEventArgs,
|
||||
} from '@0x/contracts-erc721';
|
||||
import {
|
||||
blockchainTests,
|
||||
constants,
|
||||
expect,
|
||||
getRandomInteger,
|
||||
hexRandom,
|
||||
hexSlice,
|
||||
randomAddress,
|
||||
verifyEventsFromLogs,
|
||||
} from '@0x/contracts-test-utils';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
|
||||
import { ForwarderRevertErrors } from '../src';
|
||||
|
||||
import { artifacts } from './artifacts';
|
||||
import { TestForwarderContract } from './wrappers';
|
||||
|
||||
blockchainTests('Supported asset type unit tests', env => {
|
||||
let forwarder: TestForwarderContract;
|
||||
let assetDataEncoder: IAssetDataContract;
|
||||
let bridgeAddress: string;
|
||||
let bridgeData: string;
|
||||
let receiver: string;
|
||||
|
||||
let erc20Token: DummyERC20TokenContract;
|
||||
let erc721Token: DummyERC721TokenContract;
|
||||
let nftId: BigNumber;
|
||||
|
||||
let erc20AssetData: string;
|
||||
let erc721AssetData: string;
|
||||
let erc20BridgeAssetData: string;
|
||||
|
||||
before(async () => {
|
||||
[receiver] = await env.getAccountAddressesAsync();
|
||||
assetDataEncoder = new IAssetDataContract(constants.NULL_ADDRESS, env.provider);
|
||||
|
||||
forwarder = await TestForwarderContract.deployFrom0xArtifactAsync(
|
||||
artifacts.TestForwarder,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
{ ...artifacts, ...ERC20Artifacts, ...ERC721Artifacts },
|
||||
);
|
||||
|
||||
erc20Token = await DummyERC20TokenContract.deployFrom0xArtifactAsync(
|
||||
ERC20Artifacts.DummyERC20Token,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
ERC20Artifacts,
|
||||
constants.DUMMY_TOKEN_NAME,
|
||||
constants.DUMMY_TOKEN_SYMBOL,
|
||||
constants.DUMMY_TOKEN_DECIMALS,
|
||||
constants.DUMMY_TOKEN_TOTAL_SUPPLY,
|
||||
);
|
||||
erc20AssetData = assetDataEncoder.ERC20Token(erc20Token.address).getABIEncodedTransactionData();
|
||||
|
||||
erc721Token = await DummyERC721TokenContract.deployFrom0xArtifactAsync(
|
||||
ERC721Artifacts.DummyERC721Token,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
ERC721Artifacts,
|
||||
constants.DUMMY_TOKEN_NAME,
|
||||
constants.DUMMY_TOKEN_SYMBOL,
|
||||
);
|
||||
nftId = getRandomInteger(constants.ZERO_AMOUNT, constants.MAX_UINT256);
|
||||
erc721AssetData = assetDataEncoder.ERC721Token(erc721Token.address, nftId).getABIEncodedTransactionData();
|
||||
|
||||
bridgeAddress = randomAddress();
|
||||
bridgeData = hexRandom();
|
||||
erc20BridgeAssetData = assetDataEncoder
|
||||
.ERC20Bridge(erc20Token.address, bridgeAddress, bridgeData)
|
||||
.getABIEncodedTransactionData();
|
||||
});
|
||||
|
||||
describe('_isPercentageFee', () => {
|
||||
it('returns true if takerFeeAssetData == makerAssetData are ERC20', async () => {
|
||||
const result = await forwarder.isPercentageFee(erc20AssetData, erc20AssetData).callAsync();
|
||||
expect(result).to.be.true();
|
||||
});
|
||||
it('returns true if makerAssetData is the ERC20Bridge equivalent of takerFeeAssetData', async () => {
|
||||
const result = await forwarder.isPercentageFee(erc20AssetData, erc20BridgeAssetData).callAsync();
|
||||
expect(result).to.be.true();
|
||||
});
|
||||
it('returns false if takerFeeAssetData != makerAssetData are ERC20', async () => {
|
||||
const differentERC20AssetData = assetDataEncoder.ERC20Token(randomAddress()).getABIEncodedTransactionData();
|
||||
const result = await forwarder.isPercentageFee(erc20AssetData, differentERC20AssetData).callAsync();
|
||||
expect(result).to.be.false();
|
||||
});
|
||||
it('returns false if takerFeeAssetData is ERC20 and makerAssetData is ERC721', async () => {
|
||||
const result = await forwarder.isPercentageFee(erc20AssetData, erc721AssetData).callAsync();
|
||||
expect(result).to.be.false();
|
||||
});
|
||||
it('returns false if makerAssetData us ERC20Bridge, but for a different token than takerFeeAssetData', async () => {
|
||||
const mismatchedErc20BridgeAssetData = assetDataEncoder
|
||||
.ERC20Bridge(randomAddress(), bridgeAddress, bridgeData)
|
||||
.getABIEncodedTransactionData();
|
||||
const result = await forwarder.isPercentageFee(erc20AssetData, mismatchedErc20BridgeAssetData).callAsync();
|
||||
expect(result).to.be.false();
|
||||
});
|
||||
it('returns false if takerFeeAssetData is not ERC20', async () => {
|
||||
const result = await forwarder.isPercentageFee(erc721AssetData, erc721AssetData).callAsync();
|
||||
expect(result).to.be.false();
|
||||
});
|
||||
});
|
||||
|
||||
describe('_transferAssetToSender', () => {
|
||||
const TRANSFER_AMOUNT = new BigNumber(1);
|
||||
before(async () => {
|
||||
await erc20Token
|
||||
.setBalance(forwarder.address, constants.INITIAL_ERC20_BALANCE)
|
||||
.awaitTransactionSuccessAsync();
|
||||
await erc721Token.mint(forwarder.address, nftId).awaitTransactionSuccessAsync();
|
||||
});
|
||||
|
||||
it('transfers an ERC20 token given ERC20 assetData', async () => {
|
||||
const txReceipt = await forwarder
|
||||
.transferAssetToSender(erc20AssetData, TRANSFER_AMOUNT)
|
||||
.awaitTransactionSuccessAsync({ from: receiver });
|
||||
verifyEventsFromLogs<ERC20TokenTransferEventArgs>(
|
||||
txReceipt.logs,
|
||||
[{ _from: forwarder.address, _to: receiver, _value: TRANSFER_AMOUNT }],
|
||||
ERC20TokenEvents.Transfer,
|
||||
);
|
||||
});
|
||||
it('transfers an ERC721 token given ERC721 assetData and amount == 1', async () => {
|
||||
const txReceipt = await forwarder
|
||||
.transferAssetToSender(erc721AssetData, TRANSFER_AMOUNT)
|
||||
.awaitTransactionSuccessAsync({ from: receiver });
|
||||
verifyEventsFromLogs<ERC721TokenTransferEventArgs>(
|
||||
txReceipt.logs,
|
||||
[{ _from: forwarder.address, _to: receiver, _tokenId: nftId }],
|
||||
ERC721TokenEvents.Transfer,
|
||||
);
|
||||
});
|
||||
it('reverts if attempting to transfer an ERC721 token with amount != 1', async () => {
|
||||
const invalidAmount = new BigNumber(2);
|
||||
const tx = forwarder
|
||||
.transferAssetToSender(erc721AssetData, invalidAmount)
|
||||
.awaitTransactionSuccessAsync({ from: receiver });
|
||||
const expectedError = new ForwarderRevertErrors.Erc721AmountMustEqualOneError(invalidAmount);
|
||||
expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
it('transfers an ERC20 token given ERC20Bridge assetData', async () => {
|
||||
const txReceipt = await forwarder
|
||||
.transferAssetToSender(erc20BridgeAssetData, TRANSFER_AMOUNT)
|
||||
.awaitTransactionSuccessAsync({ from: receiver });
|
||||
verifyEventsFromLogs<ERC20TokenTransferEventArgs>(
|
||||
txReceipt.logs,
|
||||
[{ _from: forwarder.address, _to: receiver, _value: TRANSFER_AMOUNT }],
|
||||
ERC20TokenEvents.Transfer,
|
||||
);
|
||||
});
|
||||
it('reverts if assetData is unsupported', async () => {
|
||||
const randomBytes = hexRandom();
|
||||
const tx = forwarder
|
||||
.transferAssetToSender(randomBytes, TRANSFER_AMOUNT)
|
||||
.awaitTransactionSuccessAsync({ from: receiver });
|
||||
const expectedError = new ForwarderRevertErrors.UnsupportedAssetProxyError(hexSlice(randomBytes, 0, 4));
|
||||
expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
});
|
||||
});
|
@ -13,3 +13,4 @@ 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_weth';
|
||||
export * from '../test/generated-wrappers/test_forwarder';
|
||||
|
@ -13,7 +13,8 @@
|
||||
"test/generated-artifacts/MixinAssets.json",
|
||||
"test/generated-artifacts/MixinExchangeWrapper.json",
|
||||
"test/generated-artifacts/MixinForwarderCore.json",
|
||||
"test/generated-artifacts/MixinWeth.json"
|
||||
"test/generated-artifacts/MixinWeth.json",
|
||||
"test/generated-artifacts/TestForwarder.json"
|
||||
],
|
||||
"exclude": ["./deploy/solc/solc_bin"]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user