aboutsummaryrefslogtreecommitdiffstats
path: root/contracts/core/test/extensions
diff options
context:
space:
mode:
authorLeonid Logvinov <logvinov.leon@gmail.com>2018-12-11 02:53:25 +0800
committerLeonid Logvinov <logvinov.leon@gmail.com>2018-12-11 02:53:25 +0800
commit924c2705b28f5821fd36d653fb3f7aa7bb015caf (patch)
tree99bd6a5ba4bc18c5fabbd40122bfec0f859e7de7 /contracts/core/test/extensions
parentb88ff0a19ff7695086107cbcffe980dc4ad84e10 (diff)
downloaddexon-sol-tools-924c2705b28f5821fd36d653fb3f7aa7bb015caf.tar.gz
dexon-sol-tools-924c2705b28f5821fd36d653fb3f7aa7bb015caf.tar.zst
dexon-sol-tools-924c2705b28f5821fd36d653fb3f7aa7bb015caf.zip
Refactor our extensions package
Diffstat (limited to 'contracts/core/test/extensions')
-rw-r--r--contracts/core/test/extensions/dutch_auction.ts455
-rw-r--r--contracts/core/test/extensions/forwarder.ts1288
-rw-r--r--contracts/core/test/extensions/order_validator.ts606
3 files changed, 0 insertions, 2349 deletions
diff --git a/contracts/core/test/extensions/dutch_auction.ts b/contracts/core/test/extensions/dutch_auction.ts
deleted file mode 100644
index b396d4206..000000000
--- a/contracts/core/test/extensions/dutch_auction.ts
+++ /dev/null
@@ -1,455 +0,0 @@
-import {
- chaiSetup,
- constants,
- ContractName,
- ERC20BalancesByOwner,
- expectTransactionFailedAsync,
- getLatestBlockTimestampAsync,
- OrderFactory,
- provider,
- txDefaults,
- web3Wrapper,
-} from '@0x/contracts-test-utils';
-import {
- artifacts as tokensArtifacts,
- DummyERC20TokenContract,
- DummyERC721TokenContract,
- WETH9Contract,
-} from '@0x/contracts-tokens';
-import { BlockchainLifecycle } from '@0x/dev-utils';
-import { assetDataUtils, generatePseudoRandomSalt } from '@0x/order-utils';
-import { RevertReason, SignedOrder } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import { Web3Wrapper } from '@0x/web3-wrapper';
-import * as chai from 'chai';
-import ethAbi = require('ethereumjs-abi');
-import * as ethUtil from 'ethereumjs-util';
-import * as _ from 'lodash';
-
-import { DutchAuctionContract } from '../../generated-wrappers/dutch_auction';
-import { ExchangeContract } from '../../generated-wrappers/exchange';
-import { artifacts } from '../../src/artifacts';
-import { ERC20Wrapper } from '../utils/erc20_wrapper';
-import { ERC721Wrapper } from '../utils/erc721_wrapper';
-import { ExchangeWrapper } from '../utils/exchange_wrapper';
-
-chaiSetup.configure();
-const expect = chai.expect;
-const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
-const DECIMALS_DEFAULT = 18;
-
-describe(ContractName.DutchAuction, () => {
- let makerAddress: string;
- let owner: string;
- let takerAddress: string;
- let feeRecipientAddress: string;
- let defaultMakerAssetAddress: string;
-
- let zrxToken: DummyERC20TokenContract;
- let erc20TokenA: DummyERC20TokenContract;
- let erc721Token: DummyERC721TokenContract;
- let dutchAuctionContract: DutchAuctionContract;
- let wethContract: WETH9Contract;
-
- let sellerOrderFactory: OrderFactory;
- let buyerOrderFactory: OrderFactory;
- let erc20Wrapper: ERC20Wrapper;
- let erc20Balances: ERC20BalancesByOwner;
- let currentBlockTimestamp: number;
- let auctionBeginTimeSeconds: BigNumber;
- let auctionEndTimeSeconds: BigNumber;
- let auctionBeginAmount: BigNumber;
- let auctionEndAmount: BigNumber;
- let sellOrder: SignedOrder;
- let buyOrder: SignedOrder;
- let erc721MakerAssetIds: BigNumber[];
- const tenMinutesInSeconds = 10 * 60;
-
- function extendMakerAssetData(makerAssetData: string, beginTimeSeconds: BigNumber, beginAmount: BigNumber): string {
- return ethUtil.bufferToHex(
- Buffer.concat([
- ethUtil.toBuffer(makerAssetData),
- ethUtil.toBuffer(
- (ethAbi as any).rawEncode(
- ['uint256', 'uint256'],
- [beginTimeSeconds.toString(), beginAmount.toString()],
- ),
- ),
- ]),
- );
- }
-
- before(async () => {
- await blockchainLifecycle.startAsync();
- const accounts = await web3Wrapper.getAvailableAddressesAsync();
- const usedAddresses = ([owner, makerAddress, takerAddress, feeRecipientAddress] = accounts);
-
- erc20Wrapper = new ERC20Wrapper(provider, usedAddresses, owner);
-
- const numDummyErc20ToDeploy = 2;
- [erc20TokenA, zrxToken] = await erc20Wrapper.deployDummyTokensAsync(
- numDummyErc20ToDeploy,
- constants.DUMMY_TOKEN_DECIMALS,
- );
- const erc20Proxy = await erc20Wrapper.deployProxyAsync();
- await erc20Wrapper.setBalancesAndAllowancesAsync();
-
- const erc721Wrapper = new ERC721Wrapper(provider, usedAddresses, owner);
- [erc721Token] = await erc721Wrapper.deployDummyTokensAsync();
- const erc721Proxy = await erc721Wrapper.deployProxyAsync();
- await erc721Wrapper.setBalancesAndAllowancesAsync();
- const erc721Balances = await erc721Wrapper.getBalancesAsync();
- erc721MakerAssetIds = erc721Balances[makerAddress][erc721Token.address];
-
- wethContract = await WETH9Contract.deployFrom0xArtifactAsync(tokensArtifacts.WETH9, provider, txDefaults);
- erc20Wrapper.addDummyTokenContract(wethContract as any);
-
- const zrxAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address);
- const exchangeInstance = await ExchangeContract.deployFrom0xArtifactAsync(
- artifacts.Exchange,
- provider,
- txDefaults,
- zrxAssetData,
- );
- const exchangeWrapper = new ExchangeWrapper(exchangeInstance, provider);
- await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, owner);
- await exchangeWrapper.registerAssetProxyAsync(erc721Proxy.address, owner);
-
- await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(exchangeInstance.address, {
- from: owner,
- });
- await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(exchangeInstance.address, {
- from: owner,
- });
-
- const dutchAuctionInstance = await DutchAuctionContract.deployFrom0xArtifactAsync(
- artifacts.DutchAuction,
- provider,
- txDefaults,
- exchangeInstance.address,
- );
- dutchAuctionContract = new DutchAuctionContract(
- dutchAuctionInstance.abi,
- dutchAuctionInstance.address,
- provider,
- );
-
- defaultMakerAssetAddress = erc20TokenA.address;
- const defaultTakerAssetAddress = wethContract.address;
-
- // Set up taker WETH balance and allowance
- await web3Wrapper.awaitTransactionSuccessAsync(
- await wethContract.deposit.sendTransactionAsync({
- from: takerAddress,
- value: Web3Wrapper.toBaseUnitAmount(new BigNumber(50), DECIMALS_DEFAULT),
- }),
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await wethContract.approve.sendTransactionAsync(
- erc20Proxy.address,
- constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
- { from: takerAddress },
- ),
- );
- web3Wrapper.abiDecoder.addABI(exchangeInstance.abi);
- web3Wrapper.abiDecoder.addABI(zrxToken.abi);
- erc20Wrapper.addTokenOwnerAddress(dutchAuctionContract.address);
-
- currentBlockTimestamp = await getLatestBlockTimestampAsync();
- // Default auction begins 10 minutes ago
- auctionBeginTimeSeconds = new BigNumber(currentBlockTimestamp).minus(tenMinutesInSeconds);
- // Default auction ends 10 from now
- auctionEndTimeSeconds = new BigNumber(currentBlockTimestamp).plus(tenMinutesInSeconds);
- auctionBeginAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(10), DECIMALS_DEFAULT);
- auctionEndAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT);
-
- // Default sell order and buy order are exact mirrors
- const sellerDefaultOrderParams = {
- salt: generatePseudoRandomSalt(),
- exchangeAddress: exchangeInstance.address,
- makerAddress,
- feeRecipientAddress,
- // taker address or sender address should be set to the ducth auction contract
- takerAddress: dutchAuctionContract.address,
- makerAssetData: extendMakerAssetData(
- assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress),
- auctionBeginTimeSeconds,
- auctionBeginAmount,
- ),
- takerAssetData: assetDataUtils.encodeERC20AssetData(defaultTakerAssetAddress),
- makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(200), DECIMALS_DEFAULT),
- takerAssetAmount: auctionEndAmount,
- expirationTimeSeconds: auctionEndTimeSeconds,
- makerFee: constants.ZERO_AMOUNT,
- takerFee: constants.ZERO_AMOUNT,
- };
- // Default buy order is for the auction begin price
- const buyerDefaultOrderParams = {
- ...sellerDefaultOrderParams,
- makerAddress: takerAddress,
- makerAssetData: sellerDefaultOrderParams.takerAssetData,
- takerAssetData: sellerDefaultOrderParams.makerAssetData,
- makerAssetAmount: auctionBeginAmount,
- takerAssetAmount: sellerDefaultOrderParams.makerAssetAmount,
- };
- const makerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)];
- const takerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(takerAddress)];
- sellerOrderFactory = new OrderFactory(makerPrivateKey, sellerDefaultOrderParams);
- buyerOrderFactory = new OrderFactory(takerPrivateKey, buyerDefaultOrderParams);
- });
- after(async () => {
- await blockchainLifecycle.revertAsync();
- });
- beforeEach(async () => {
- await blockchainLifecycle.startAsync();
- erc20Balances = await erc20Wrapper.getBalancesAsync();
- sellOrder = await sellerOrderFactory.newSignedOrderAsync();
- buyOrder = await buyerOrderFactory.newSignedOrderAsync();
- });
- afterEach(async () => {
- await blockchainLifecycle.revertAsync();
- });
- describe('matchOrders', () => {
- it('should be worth the begin price at the begining of the auction', async () => {
- auctionBeginTimeSeconds = new BigNumber(currentBlockTimestamp + 2);
- sellOrder = await sellerOrderFactory.newSignedOrderAsync({
- makerAssetData: extendMakerAssetData(
- assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress),
- auctionBeginTimeSeconds,
- auctionBeginAmount,
- ),
- });
- const auctionDetails = await dutchAuctionContract.getAuctionDetails.callAsync(sellOrder);
- expect(auctionDetails.currentAmount).to.be.bignumber.equal(auctionBeginAmount);
- expect(auctionDetails.beginAmount).to.be.bignumber.equal(auctionBeginAmount);
- });
- it('should be be worth the end price at the end of the auction', async () => {
- auctionBeginTimeSeconds = new BigNumber(currentBlockTimestamp - tenMinutesInSeconds * 2);
- auctionEndTimeSeconds = new BigNumber(currentBlockTimestamp - tenMinutesInSeconds);
- sellOrder = await sellerOrderFactory.newSignedOrderAsync({
- makerAssetData: extendMakerAssetData(
- assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress),
- auctionBeginTimeSeconds,
- auctionBeginAmount,
- ),
- expirationTimeSeconds: auctionEndTimeSeconds,
- });
- const auctionDetails = await dutchAuctionContract.getAuctionDetails.callAsync(sellOrder);
- expect(auctionDetails.currentAmount).to.be.bignumber.equal(auctionEndAmount);
- expect(auctionDetails.beginAmount).to.be.bignumber.equal(auctionBeginAmount);
- });
- it('should match orders at current amount and send excess to buyer', async () => {
- const beforeAuctionDetails = await dutchAuctionContract.getAuctionDetails.callAsync(sellOrder);
- buyOrder = await buyerOrderFactory.newSignedOrderAsync({
- makerAssetAmount: beforeAuctionDetails.currentAmount.times(2),
- });
- await web3Wrapper.awaitTransactionSuccessAsync(
- await dutchAuctionContract.matchOrders.sendTransactionAsync(
- buyOrder,
- sellOrder,
- buyOrder.signature,
- sellOrder.signature,
- {
- from: takerAddress,
- },
- ),
- );
- const afterAuctionDetails = await dutchAuctionContract.getAuctionDetails.callAsync(sellOrder);
- const newBalances = await erc20Wrapper.getBalancesAsync();
- expect(newBalances[dutchAuctionContract.address][wethContract.address]).to.be.bignumber.equal(
- constants.ZERO_AMOUNT,
- );
- // HACK gte used here due to a bug in ganache where the timestamp can change
- // between multiple calls to the same block. Which can move the amount in our case
- // ref: https://github.com/trufflesuite/ganache-core/issues/111
- expect(newBalances[makerAddress][wethContract.address]).to.be.bignumber.gte(
- erc20Balances[makerAddress][wethContract.address].plus(afterAuctionDetails.currentAmount),
- );
- expect(newBalances[takerAddress][wethContract.address]).to.be.bignumber.gte(
- erc20Balances[takerAddress][wethContract.address].minus(beforeAuctionDetails.currentAmount),
- );
- });
- it('maker fees on sellOrder are paid to the fee receipient', async () => {
- sellOrder = await sellerOrderFactory.newSignedOrderAsync({
- makerFee: new BigNumber(1),
- });
- const txHash = await dutchAuctionContract.matchOrders.sendTransactionAsync(
- buyOrder,
- sellOrder,
- buyOrder.signature,
- sellOrder.signature,
- {
- from: takerAddress,
- },
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const afterAuctionDetails = await dutchAuctionContract.getAuctionDetails.callAsync(sellOrder);
- const newBalances = await erc20Wrapper.getBalancesAsync();
- expect(newBalances[makerAddress][wethContract.address]).to.be.bignumber.gte(
- erc20Balances[makerAddress][wethContract.address].plus(afterAuctionDetails.currentAmount),
- );
- expect(newBalances[feeRecipientAddress][zrxToken.address]).to.be.bignumber.equal(
- erc20Balances[feeRecipientAddress][zrxToken.address].plus(sellOrder.makerFee),
- );
- });
- it('maker fees on buyOrder are paid to the fee receipient', async () => {
- buyOrder = await buyerOrderFactory.newSignedOrderAsync({
- makerFee: new BigNumber(1),
- });
- const txHash = await dutchAuctionContract.matchOrders.sendTransactionAsync(
- buyOrder,
- sellOrder,
- buyOrder.signature,
- sellOrder.signature,
- {
- from: takerAddress,
- },
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const newBalances = await erc20Wrapper.getBalancesAsync();
- const afterAuctionDetails = await dutchAuctionContract.getAuctionDetails.callAsync(sellOrder);
- expect(newBalances[makerAddress][wethContract.address]).to.be.bignumber.gte(
- erc20Balances[makerAddress][wethContract.address].plus(afterAuctionDetails.currentAmount),
- );
- expect(newBalances[feeRecipientAddress][zrxToken.address]).to.be.bignumber.equal(
- erc20Balances[feeRecipientAddress][zrxToken.address].plus(buyOrder.makerFee),
- );
- });
- it('should revert when auction expires', async () => {
- auctionBeginTimeSeconds = new BigNumber(currentBlockTimestamp - tenMinutesInSeconds * 2);
- auctionEndTimeSeconds = new BigNumber(currentBlockTimestamp - tenMinutesInSeconds);
- sellOrder = await sellerOrderFactory.newSignedOrderAsync({
- expirationTimeSeconds: auctionEndTimeSeconds,
- makerAssetData: extendMakerAssetData(
- assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress),
- auctionBeginTimeSeconds,
- auctionBeginAmount,
- ),
- });
- return expectTransactionFailedAsync(
- dutchAuctionContract.matchOrders.sendTransactionAsync(
- buyOrder,
- sellOrder,
- buyOrder.signature,
- sellOrder.signature,
- {
- from: takerAddress,
- },
- ),
- RevertReason.AuctionExpired,
- );
- });
- it('cannot be filled for less than the current price', async () => {
- buyOrder = await buyerOrderFactory.newSignedOrderAsync({
- makerAssetAmount: sellOrder.takerAssetAmount,
- });
- return expectTransactionFailedAsync(
- dutchAuctionContract.matchOrders.sendTransactionAsync(
- buyOrder,
- sellOrder,
- buyOrder.signature,
- sellOrder.signature,
- {
- from: takerAddress,
- },
- ),
- RevertReason.AuctionInvalidAmount,
- );
- });
- it('auction begin amount must be higher than final amount ', async () => {
- sellOrder = await sellerOrderFactory.newSignedOrderAsync({
- takerAssetAmount: auctionBeginAmount.plus(1),
- });
- return expectTransactionFailedAsync(
- dutchAuctionContract.matchOrders.sendTransactionAsync(
- buyOrder,
- sellOrder,
- buyOrder.signature,
- sellOrder.signature,
- {
- from: takerAddress,
- },
- ),
- RevertReason.AuctionInvalidAmount,
- );
- });
- it('begin time is less than end time', async () => {
- auctionBeginTimeSeconds = new BigNumber(auctionEndTimeSeconds).plus(tenMinutesInSeconds);
- sellOrder = await sellerOrderFactory.newSignedOrderAsync({
- expirationTimeSeconds: auctionEndTimeSeconds,
- makerAssetData: extendMakerAssetData(
- assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress),
- auctionBeginTimeSeconds,
- auctionBeginAmount,
- ),
- });
- return expectTransactionFailedAsync(
- dutchAuctionContract.matchOrders.sendTransactionAsync(
- buyOrder,
- sellOrder,
- buyOrder.signature,
- sellOrder.signature,
- {
- from: takerAddress,
- },
- ),
- RevertReason.AuctionInvalidBeginTime,
- );
- });
- it('asset data contains auction parameters', async () => {
- sellOrder = await sellerOrderFactory.newSignedOrderAsync({
- makerAssetData: assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress),
- });
- return expectTransactionFailedAsync(
- dutchAuctionContract.matchOrders.sendTransactionAsync(
- buyOrder,
- sellOrder,
- buyOrder.signature,
- sellOrder.signature,
- {
- from: takerAddress,
- },
- ),
- RevertReason.InvalidAssetData,
- );
- });
- describe('ERC721', () => {
- it('should match orders when ERC721', async () => {
- const makerAssetId = erc721MakerAssetIds[0];
- sellOrder = await sellerOrderFactory.newSignedOrderAsync({
- makerAssetAmount: new BigNumber(1),
- makerAssetData: extendMakerAssetData(
- assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
- auctionBeginTimeSeconds,
- auctionBeginAmount,
- ),
- });
- buyOrder = await buyerOrderFactory.newSignedOrderAsync({
- takerAssetAmount: new BigNumber(1),
- takerAssetData: sellOrder.makerAssetData,
- });
- await web3Wrapper.awaitTransactionSuccessAsync(
- await dutchAuctionContract.matchOrders.sendTransactionAsync(
- buyOrder,
- sellOrder,
- buyOrder.signature,
- sellOrder.signature,
- {
- from: takerAddress,
- },
- ),
- );
- const afterAuctionDetails = await dutchAuctionContract.getAuctionDetails.callAsync(sellOrder);
- const newBalances = await erc20Wrapper.getBalancesAsync();
- // HACK gte used here due to a bug in ganache where the timestamp can change
- // between multiple calls to the same block. Which can move the amount in our case
- // ref: https://github.com/trufflesuite/ganache-core/issues/111
- expect(newBalances[makerAddress][wethContract.address]).to.be.bignumber.gte(
- erc20Balances[makerAddress][wethContract.address].plus(afterAuctionDetails.currentAmount),
- );
- const newOwner = await erc721Token.ownerOf.callAsync(makerAssetId);
- expect(newOwner).to.be.bignumber.equal(takerAddress);
- });
- });
- });
-});
diff --git a/contracts/core/test/extensions/forwarder.ts b/contracts/core/test/extensions/forwarder.ts
deleted file mode 100644
index ffa015dd2..000000000
--- a/contracts/core/test/extensions/forwarder.ts
+++ /dev/null
@@ -1,1288 +0,0 @@
-import {
- chaiSetup,
- constants,
- ContractName,
- ERC20BalancesByOwner,
- expectContractCreationFailedAsync,
- expectTransactionFailedAsync,
- OrderFactory,
- provider,
- sendTransactionResult,
- txDefaults,
- web3Wrapper,
-} from '@0x/contracts-test-utils';
-import {
- artifacts as tokenArtifacts,
- DummyERC20TokenContract,
- DummyERC721TokenContract,
- WETH9Contract,
-} from '@0x/contracts-tokens';
-import { BlockchainLifecycle } from '@0x/dev-utils';
-import { assetDataUtils } from '@0x/order-utils';
-import { RevertReason, SignedOrder } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import { Web3Wrapper } from '@0x/web3-wrapper';
-import * as chai from 'chai';
-import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
-
-import { ExchangeContract } from '../../generated-wrappers/exchange';
-import { ForwarderContract } from '../../generated-wrappers/forwarder';
-import { artifacts } from '../../src/artifacts';
-import { ERC20Wrapper } from '../utils/erc20_wrapper';
-import { ERC721Wrapper } from '../utils/erc721_wrapper';
-import { ExchangeWrapper } from '../utils/exchange_wrapper';
-import { ForwarderWrapper } from '../utils/forwarder_wrapper';
-
-chaiSetup.configure();
-const expect = chai.expect;
-const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
-const DECIMALS_DEFAULT = 18;
-const MAX_WETH_FILL_PERCENTAGE = 95;
-
-describe(ContractName.Forwarder, () => {
- let makerAddress: string;
- let owner: string;
- let takerAddress: string;
- let feeRecipientAddress: string;
- let otherAddress: string;
- let defaultMakerAssetAddress: string;
- let zrxAssetData: string;
- let wethAssetData: string;
-
- let weth: DummyERC20TokenContract;
- let zrxToken: DummyERC20TokenContract;
- let erc20TokenA: DummyERC20TokenContract;
- let erc721Token: DummyERC721TokenContract;
- let forwarderContract: ForwarderContract;
- let wethContract: WETH9Contract;
- let forwarderWrapper: ForwarderWrapper;
- let exchangeWrapper: ExchangeWrapper;
-
- let orderWithoutFee: SignedOrder;
- let orderWithFee: SignedOrder;
- let feeOrder: SignedOrder;
- let orderFactory: OrderFactory;
- let erc20Wrapper: ERC20Wrapper;
- let erc20Balances: ERC20BalancesByOwner;
- let tx: TransactionReceiptWithDecodedLogs;
-
- let erc721MakerAssetIds: BigNumber[];
- let takerEthBalanceBefore: BigNumber;
- let feePercentage: BigNumber;
- let gasPrice: BigNumber;
-
- before(async () => {
- await blockchainLifecycle.startAsync();
- const accounts = await web3Wrapper.getAvailableAddressesAsync();
- const usedAddresses = ([owner, makerAddress, takerAddress, feeRecipientAddress, otherAddress] = accounts);
-
- const txHash = await web3Wrapper.sendTransactionAsync({ from: accounts[0], to: accounts[0], value: 0 });
- const transaction = await web3Wrapper.getTransactionByHashAsync(txHash);
- gasPrice = new BigNumber(transaction.gasPrice);
-
- const erc721Wrapper = new ERC721Wrapper(provider, usedAddresses, owner);
- erc20Wrapper = new ERC20Wrapper(provider, usedAddresses, owner);
-
- const numDummyErc20ToDeploy = 3;
- [erc20TokenA, zrxToken] = await erc20Wrapper.deployDummyTokensAsync(
- numDummyErc20ToDeploy,
- constants.DUMMY_TOKEN_DECIMALS,
- );
- const erc20Proxy = await erc20Wrapper.deployProxyAsync();
- await erc20Wrapper.setBalancesAndAllowancesAsync();
-
- [erc721Token] = await erc721Wrapper.deployDummyTokensAsync();
- const erc721Proxy = await erc721Wrapper.deployProxyAsync();
- await erc721Wrapper.setBalancesAndAllowancesAsync();
- const erc721Balances = await erc721Wrapper.getBalancesAsync();
- erc721MakerAssetIds = erc721Balances[makerAddress][erc721Token.address];
-
- wethContract = await WETH9Contract.deployFrom0xArtifactAsync(tokenArtifacts.WETH9, provider, txDefaults);
- weth = new DummyERC20TokenContract(wethContract.abi, wethContract.address, provider);
- erc20Wrapper.addDummyTokenContract(weth);
-
- wethAssetData = assetDataUtils.encodeERC20AssetData(wethContract.address);
- zrxAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address);
- const exchangeInstance = await ExchangeContract.deployFrom0xArtifactAsync(
- artifacts.Exchange,
- provider,
- txDefaults,
- zrxAssetData,
- );
- exchangeWrapper = new ExchangeWrapper(exchangeInstance, provider);
- await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, owner);
- await exchangeWrapper.registerAssetProxyAsync(erc721Proxy.address, owner);
-
- await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(exchangeInstance.address, {
- from: owner,
- });
- await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(exchangeInstance.address, {
- from: owner,
- });
-
- defaultMakerAssetAddress = erc20TokenA.address;
- const defaultTakerAssetAddress = wethContract.address;
- const defaultOrderParams = {
- exchangeAddress: exchangeInstance.address,
- makerAddress,
- feeRecipientAddress,
- makerAssetData: assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress),
- takerAssetData: assetDataUtils.encodeERC20AssetData(defaultTakerAssetAddress),
- makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(200), DECIMALS_DEFAULT),
- takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), DECIMALS_DEFAULT),
- makerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
- takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(0), DECIMALS_DEFAULT),
- };
- const privateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)];
- orderFactory = new OrderFactory(privateKey, defaultOrderParams);
-
- const forwarderInstance = await ForwarderContract.deployFrom0xArtifactAsync(
- artifacts.Forwarder,
- provider,
- txDefaults,
- exchangeInstance.address,
- zrxAssetData,
- wethAssetData,
- );
- forwarderContract = new ForwarderContract(forwarderInstance.abi, forwarderInstance.address, provider);
- forwarderWrapper = new ForwarderWrapper(forwarderContract, provider);
- const zrxDepositAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(10000), 18);
- await web3Wrapper.awaitTransactionSuccessAsync(
- await zrxToken.transfer.sendTransactionAsync(forwarderContract.address, zrxDepositAmount),
- );
- erc20Wrapper.addTokenOwnerAddress(forwarderInstance.address);
- });
- after(async () => {
- await blockchainLifecycle.revertAsync();
- });
- beforeEach(async () => {
- await blockchainLifecycle.startAsync();
- erc20Balances = await erc20Wrapper.getBalancesAsync();
- takerEthBalanceBefore = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- orderWithoutFee = await orderFactory.newSignedOrderAsync();
- feeOrder = await orderFactory.newSignedOrderAsync({
- makerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
- takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
- });
- orderWithFee = await orderFactory.newSignedOrderAsync({
- takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
- });
- });
- afterEach(async () => {
- await blockchainLifecycle.revertAsync();
- });
-
- describe('constructor', () => {
- it('should revert if assetProxy is unregistered', async () => {
- const exchangeInstance = await ExchangeContract.deployFrom0xArtifactAsync(
- artifacts.Exchange,
- provider,
- txDefaults,
- zrxAssetData,
- );
- return expectContractCreationFailedAsync(
- (ForwarderContract.deployFrom0xArtifactAsync(
- artifacts.Forwarder,
- provider,
- txDefaults,
- exchangeInstance.address,
- zrxAssetData,
- wethAssetData,
- ) as any) as sendTransactionResult,
- RevertReason.UnregisteredAssetProxy,
- );
- });
- });
- describe('marketSellOrdersWithEth without extra fees', () => {
- it('should fill a single order', async () => {
- const ordersWithoutFee = [orderWithoutFee];
- const feeOrders: SignedOrder[] = [];
- const ethValue = orderWithoutFee.takerAssetAmount.dividedToIntegerBy(2);
-
- tx = await forwarderWrapper.marketSellOrdersWithEthAsync(ordersWithoutFee, feeOrders, {
- value: ethValue,
- from: takerAddress,
- });
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const newBalances = await erc20Wrapper.getBalancesAsync();
-
- const primaryTakerAssetFillAmount = ForwarderWrapper.getPercentageOfValue(
- ethValue,
- MAX_WETH_FILL_PERCENTAGE,
- );
- const makerAssetFillAmount = primaryTakerAssetFillAmount
- .times(orderWithoutFee.makerAssetAmount)
- .dividedToIntegerBy(orderWithoutFee.takerAssetAmount);
- const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
-
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
- );
- expect(newBalances[takerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[takerAddress][defaultMakerAssetAddress].plus(makerAssetFillAmount),
- );
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(newBalances[forwarderContract.address][defaultMakerAssetAddress]).to.be.bignumber.equal(
- constants.ZERO_AMOUNT,
- );
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should fill multiple orders', async () => {
- const secondOrderWithoutFee = await orderFactory.newSignedOrderAsync();
- const ordersWithoutFee = [orderWithoutFee, secondOrderWithoutFee];
- const feeOrders: SignedOrder[] = [];
- const ethValue = ordersWithoutFee[0].takerAssetAmount.plus(
- ordersWithoutFee[1].takerAssetAmount.dividedToIntegerBy(2),
- );
-
- tx = await forwarderWrapper.marketSellOrdersWithEthAsync(ordersWithoutFee, feeOrders, {
- value: ethValue,
- from: takerAddress,
- });
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const newBalances = await erc20Wrapper.getBalancesAsync();
-
- const primaryTakerAssetFillAmount = ForwarderWrapper.getPercentageOfValue(
- ethValue,
- MAX_WETH_FILL_PERCENTAGE,
- );
- const firstTakerAssetFillAmount = ordersWithoutFee[0].takerAssetAmount;
- const secondTakerAssetFillAmount = primaryTakerAssetFillAmount.minus(firstTakerAssetFillAmount);
-
- const makerAssetFillAmount = ordersWithoutFee[0].makerAssetAmount.plus(
- ordersWithoutFee[1].makerAssetAmount
- .times(secondTakerAssetFillAmount)
- .dividedToIntegerBy(ordersWithoutFee[1].takerAssetAmount),
- );
- const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
- );
- expect(newBalances[takerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[takerAddress][defaultMakerAssetAddress].plus(makerAssetFillAmount),
- );
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(newBalances[forwarderContract.address][defaultMakerAssetAddress]).to.be.bignumber.equal(
- constants.ZERO_AMOUNT,
- );
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should fill the order and pay ZRX fees from a single feeOrder', async () => {
- const ordersWithFee = [orderWithFee];
- const feeOrders = [feeOrder];
- const ethValue = orderWithFee.takerAssetAmount.dividedToIntegerBy(2);
-
- tx = await forwarderWrapper.marketSellOrdersWithEthAsync(ordersWithFee, feeOrders, {
- value: ethValue,
- from: takerAddress,
- });
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const newBalances = await erc20Wrapper.getBalancesAsync();
-
- const primaryTakerAssetFillAmount = ForwarderWrapper.getPercentageOfValue(
- ethValue,
- MAX_WETH_FILL_PERCENTAGE,
- );
- const makerAssetFillAmount = primaryTakerAssetFillAmount
- .times(orderWithoutFee.makerAssetAmount)
- .dividedToIntegerBy(orderWithoutFee.takerAssetAmount);
- const feeAmount = ForwarderWrapper.getPercentageOfValue(
- orderWithFee.takerFee.dividedToIntegerBy(2),
- MAX_WETH_FILL_PERCENTAGE,
- );
- const wethSpentOnFeeOrders = ForwarderWrapper.getWethForFeeOrders(feeAmount, feeOrders);
- const totalEthSpent = primaryTakerAssetFillAmount
- .plus(wethSpentOnFeeOrders)
- .plus(gasPrice.times(tx.gasUsed));
-
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
- );
- expect(newBalances[takerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[takerAddress][defaultMakerAssetAddress].plus(makerAssetFillAmount),
- );
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount).plus(wethSpentOnFeeOrders),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(newBalances[forwarderContract.address][defaultMakerAssetAddress]).to.be.bignumber.equal(
- constants.ZERO_AMOUNT,
- );
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should fill the orders and pay ZRX from multiple feeOrders', async () => {
- const ordersWithFee = [orderWithFee];
- const ethValue = orderWithFee.takerAssetAmount;
- const makerAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address);
- const makerAssetAmount = orderWithFee.takerFee.dividedToIntegerBy(2);
- const takerAssetAmount = feeOrder.takerAssetAmount
- .times(makerAssetAmount)
- .dividedToIntegerBy(feeOrder.makerAssetAmount);
-
- const firstFeeOrder = await orderFactory.newSignedOrderAsync({
- makerAssetData,
- makerAssetAmount,
- takerAssetAmount,
- });
- const secondFeeOrder = await orderFactory.newSignedOrderAsync({
- makerAssetData,
- makerAssetAmount,
- takerAssetAmount,
- });
- const feeOrders = [firstFeeOrder, secondFeeOrder];
-
- tx = await forwarderWrapper.marketSellOrdersWithEthAsync(ordersWithFee, feeOrders, {
- value: ethValue,
- from: takerAddress,
- });
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const newBalances = await erc20Wrapper.getBalancesAsync();
-
- const primaryTakerAssetFillAmount = ForwarderWrapper.getPercentageOfValue(
- ethValue,
- MAX_WETH_FILL_PERCENTAGE,
- );
- const makerAssetFillAmount = primaryTakerAssetFillAmount
- .times(orderWithoutFee.makerAssetAmount)
- .dividedToIntegerBy(orderWithoutFee.takerAssetAmount);
- const feeAmount = ForwarderWrapper.getPercentageOfValue(orderWithFee.takerFee, MAX_WETH_FILL_PERCENTAGE);
- const wethSpentOnFeeOrders = ForwarderWrapper.getWethForFeeOrders(feeAmount, feeOrders);
- const totalEthSpent = primaryTakerAssetFillAmount
- .plus(wethSpentOnFeeOrders)
- .plus(gasPrice.times(tx.gasUsed));
-
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
- );
- expect(newBalances[takerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[takerAddress][defaultMakerAssetAddress].plus(makerAssetFillAmount),
- );
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount).plus(wethSpentOnFeeOrders),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(newBalances[forwarderContract.address][defaultMakerAssetAddress]).to.be.bignumber.equal(
- constants.ZERO_AMOUNT,
- );
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should fill the order when token is ZRX with fees', async () => {
- orderWithFee = await orderFactory.newSignedOrderAsync({
- makerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
- takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
- });
- const ordersWithFee = [orderWithFee];
- const feeOrders: SignedOrder[] = [];
- const ethValue = orderWithFee.takerAssetAmount.dividedToIntegerBy(2);
-
- tx = await forwarderWrapper.marketSellOrdersWithEthAsync(ordersWithFee, feeOrders, {
- value: ethValue,
- from: takerAddress,
- });
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const newBalances = await erc20Wrapper.getBalancesAsync();
-
- const makerAssetFillAmount = orderWithFee.makerAssetAmount.dividedToIntegerBy(2);
- const totalEthSpent = ethValue.plus(gasPrice.times(tx.gasUsed));
- const takerFeePaid = orderWithFee.takerFee.dividedToIntegerBy(2);
- const makerFeePaid = orderWithFee.makerFee.dividedToIntegerBy(2);
-
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][zrxToken.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][zrxToken.address].minus(makerAssetFillAmount).minus(makerFeePaid),
- );
- expect(newBalances[takerAddress][zrxToken.address]).to.be.bignumber.equal(
- erc20Balances[takerAddress][zrxToken.address].plus(makerAssetFillAmount).minus(takerFeePaid),
- );
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(ethValue),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(newBalances[forwarderContract.address][zrxToken.address]).to.be.bignumber.equal(
- erc20Balances[forwarderContract.address][zrxToken.address],
- );
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should refund remaining ETH if amount is greater than takerAssetAmount', async () => {
- const ordersWithoutFee = [orderWithoutFee];
- const feeOrders: SignedOrder[] = [];
- const ethValue = orderWithoutFee.takerAssetAmount.times(2);
-
- tx = await forwarderWrapper.marketSellOrdersWithEthAsync(ordersWithoutFee, feeOrders, {
- value: ethValue,
- from: takerAddress,
- });
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const totalEthSpent = orderWithoutFee.takerAssetAmount.plus(gasPrice.times(tx.gasUsed));
-
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- });
- it('should revert if ZRX cannot be fully repurchased', async () => {
- orderWithFee = await orderFactory.newSignedOrderAsync({
- takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(50), DECIMALS_DEFAULT),
- });
- const ordersWithFee = [orderWithFee];
- feeOrder = await orderFactory.newSignedOrderAsync({
- makerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
- makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
- });
- const feeOrders = [feeOrder];
- const ethValue = orderWithFee.takerAssetAmount;
- return expectTransactionFailedAsync(
- forwarderWrapper.marketSellOrdersWithEthAsync(ordersWithFee, feeOrders, {
- value: ethValue,
- from: takerAddress,
- }),
- RevertReason.CompleteFillFailed,
- );
- });
- it('should not fill orders with different makerAssetData than the first order', async () => {
- const makerAssetId = erc721MakerAssetIds[0];
- const erc721SignedOrder = await orderFactory.newSignedOrderAsync({
- makerAssetAmount: new BigNumber(1),
- makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
- });
- const erc20SignedOrder = await orderFactory.newSignedOrderAsync();
- const ordersWithoutFee = [erc20SignedOrder, erc721SignedOrder];
- const feeOrders: SignedOrder[] = [];
- const ethValue = erc20SignedOrder.takerAssetAmount.plus(erc721SignedOrder.takerAssetAmount);
-
- tx = await forwarderWrapper.marketSellOrdersWithEthAsync(ordersWithoutFee, feeOrders, {
- value: ethValue,
- from: takerAddress,
- });
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const totalEthSpent = erc20SignedOrder.takerAssetAmount.plus(gasPrice.times(tx.gasUsed));
-
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- });
- });
- describe('marketSellOrdersWithEth with extra fees', () => {
- it('should fill the order and send fee to feeRecipient', async () => {
- const ordersWithoutFee = [orderWithoutFee];
- const feeOrders: SignedOrder[] = [];
- const ethValue = orderWithoutFee.takerAssetAmount.div(2);
-
- const baseFeePercentage = 2;
- feePercentage = ForwarderWrapper.getPercentageOfValue(constants.PERCENTAGE_DENOMINATOR, baseFeePercentage);
- const feeRecipientEthBalanceBefore = await web3Wrapper.getBalanceInWeiAsync(feeRecipientAddress);
- tx = await forwarderWrapper.marketSellOrdersWithEthAsync(
- ordersWithoutFee,
- feeOrders,
- {
- value: ethValue,
- from: takerAddress,
- },
- { feePercentage, feeRecipient: feeRecipientAddress },
- );
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const feeRecipientEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(feeRecipientAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const newBalances = await erc20Wrapper.getBalancesAsync();
-
- const primaryTakerAssetFillAmount = ForwarderWrapper.getPercentageOfValue(
- ethValue,
- MAX_WETH_FILL_PERCENTAGE,
- );
- const makerAssetFillAmount = primaryTakerAssetFillAmount
- .times(orderWithoutFee.makerAssetAmount)
- .dividedToIntegerBy(orderWithoutFee.takerAssetAmount);
- const ethSpentOnFee = ForwarderWrapper.getPercentageOfValue(primaryTakerAssetFillAmount, baseFeePercentage);
- const totalEthSpent = primaryTakerAssetFillAmount.plus(ethSpentOnFee).plus(gasPrice.times(tx.gasUsed));
-
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
- );
- expect(newBalances[takerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[takerAddress][defaultMakerAssetAddress].plus(makerAssetFillAmount),
- );
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(newBalances[forwarderContract.address][defaultMakerAssetAddress]).to.be.bignumber.equal(
- constants.ZERO_AMOUNT,
- );
- expect(feeRecipientEthBalanceAfter).to.be.bignumber.equal(feeRecipientEthBalanceBefore.plus(ethSpentOnFee));
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should fail if the fee is set too high', async () => {
- const ethValue = orderWithoutFee.takerAssetAmount.div(2);
- const baseFeePercentage = 6;
- feePercentage = ForwarderWrapper.getPercentageOfValue(ethValue, baseFeePercentage);
- const ordersWithoutFee = [orderWithoutFee];
- const feeOrders: SignedOrder[] = [];
- await expectTransactionFailedAsync(
- forwarderWrapper.marketSellOrdersWithEthAsync(
- ordersWithoutFee,
- feeOrders,
- { from: takerAddress, value: ethValue, gasPrice },
- { feePercentage, feeRecipient: feeRecipientAddress },
- ),
- RevertReason.FeePercentageTooLarge,
- );
- });
- it('should fail if there is not enough ETH remaining to pay the fee', async () => {
- const ethValue = orderWithoutFee.takerAssetAmount.div(2);
- const baseFeePercentage = 5;
- feePercentage = ForwarderWrapper.getPercentageOfValue(constants.PERCENTAGE_DENOMINATOR, baseFeePercentage);
- const ordersWithFee = [orderWithFee];
- const feeOrders = [feeOrder];
- await expectTransactionFailedAsync(
- forwarderWrapper.marketSellOrdersWithEthAsync(
- ordersWithFee,
- feeOrders,
- { from: takerAddress, value: ethValue, gasPrice },
- { feePercentage, feeRecipient: feeRecipientAddress },
- ),
- RevertReason.InsufficientEthRemaining,
- );
- });
- });
- describe('marketBuyOrdersWithEth without extra fees', () => {
- it('should buy the exact amount of makerAsset in a single order', async () => {
- const ordersWithoutFee = [orderWithoutFee];
- const feeOrders: SignedOrder[] = [];
- const makerAssetFillAmount = orderWithoutFee.makerAssetAmount.dividedToIntegerBy(2);
- const ethValue = orderWithoutFee.takerAssetAmount.dividedToIntegerBy(2);
-
- tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(ordersWithoutFee, feeOrders, makerAssetFillAmount, {
- value: ethValue,
- from: takerAddress,
- });
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const newBalances = await erc20Wrapper.getBalancesAsync();
-
- const primaryTakerAssetFillAmount = ethValue;
- const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
-
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
- );
- expect(newBalances[takerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[takerAddress][defaultMakerAssetAddress].plus(makerAssetFillAmount),
- );
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(newBalances[forwarderContract.address][defaultMakerAssetAddress]).to.be.bignumber.equal(
- constants.ZERO_AMOUNT,
- );
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should buy the exact amount of makerAsset in multiple orders', async () => {
- const secondOrderWithoutFee = await orderFactory.newSignedOrderAsync();
- const ordersWithoutFee = [orderWithoutFee, secondOrderWithoutFee];
- const feeOrders: SignedOrder[] = [];
- const makerAssetFillAmount = ordersWithoutFee[0].makerAssetAmount.plus(
- ordersWithoutFee[1].makerAssetAmount.dividedToIntegerBy(2),
- );
- const ethValue = ordersWithoutFee[0].takerAssetAmount.plus(
- ordersWithoutFee[1].takerAssetAmount.dividedToIntegerBy(2),
- );
-
- tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(ordersWithoutFee, feeOrders, makerAssetFillAmount, {
- value: ethValue,
- from: takerAddress,
- });
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const newBalances = await erc20Wrapper.getBalancesAsync();
-
- const primaryTakerAssetFillAmount = ethValue;
- const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
-
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
- );
- expect(newBalances[takerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[takerAddress][defaultMakerAssetAddress].plus(makerAssetFillAmount),
- );
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(newBalances[forwarderContract.address][defaultMakerAssetAddress]).to.be.bignumber.equal(
- constants.ZERO_AMOUNT,
- );
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should buy the exact amount of makerAsset and return excess ETH', async () => {
- const ordersWithoutFee = [orderWithoutFee];
- const feeOrders: SignedOrder[] = [];
- const makerAssetFillAmount = orderWithoutFee.makerAssetAmount.dividedToIntegerBy(2);
- const ethValue = orderWithoutFee.takerAssetAmount;
-
- tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(ordersWithoutFee, feeOrders, makerAssetFillAmount, {
- value: ethValue,
- from: takerAddress,
- });
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const newBalances = await erc20Wrapper.getBalancesAsync();
-
- const primaryTakerAssetFillAmount = ethValue.dividedToIntegerBy(2);
- const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
-
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
- );
- expect(newBalances[takerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[takerAddress][defaultMakerAssetAddress].plus(makerAssetFillAmount),
- );
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(newBalances[forwarderContract.address][defaultMakerAssetAddress]).to.be.bignumber.equal(
- constants.ZERO_AMOUNT,
- );
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should buy the exact amount of makerAsset and pay ZRX from feeOrders', async () => {
- const ordersWithFee = [orderWithFee];
- const feeOrders = [feeOrder];
- const makerAssetFillAmount = orderWithFee.makerAssetAmount.dividedToIntegerBy(2);
- const ethValue = orderWithFee.takerAssetAmount;
-
- tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(ordersWithFee, feeOrders, makerAssetFillAmount, {
- value: ethValue,
- from: takerAddress,
- });
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const newBalances = await erc20Wrapper.getBalancesAsync();
-
- const primaryTakerAssetFillAmount = orderWithFee.takerAssetAmount.dividedToIntegerBy(2);
- const feeAmount = orderWithFee.takerFee.dividedToIntegerBy(2);
- const wethSpentOnFeeOrders = ForwarderWrapper.getWethForFeeOrders(feeAmount, feeOrders);
- const totalEthSpent = primaryTakerAssetFillAmount
- .plus(wethSpentOnFeeOrders)
- .plus(gasPrice.times(tx.gasUsed));
-
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
- );
- expect(newBalances[takerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[takerAddress][defaultMakerAssetAddress].plus(makerAssetFillAmount),
- );
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount).plus(wethSpentOnFeeOrders),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(newBalances[forwarderContract.address][defaultMakerAssetAddress]).to.be.bignumber.equal(
- constants.ZERO_AMOUNT,
- );
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should buy slightly greater than makerAssetAmount when buying ZRX', async () => {
- orderWithFee = await orderFactory.newSignedOrderAsync({
- makerAssetData: assetDataUtils.encodeERC20AssetData(zrxToken.address),
- takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
- });
- const ordersWithFee = [orderWithFee];
- const feeOrders: SignedOrder[] = [];
- const makerAssetFillAmount = orderWithFee.makerAssetAmount.dividedToIntegerBy(2);
- const ethValue = orderWithFee.takerAssetAmount;
- tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(ordersWithFee, feeOrders, makerAssetFillAmount, {
- value: ethValue,
- from: takerAddress,
- });
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const newBalances = await erc20Wrapper.getBalancesAsync();
-
- const primaryTakerAssetFillAmount = ForwarderWrapper.getWethForFeeOrders(
- makerAssetFillAmount,
- ordersWithFee,
- );
- const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
- const makerAssetFilledAmount = orderWithFee.makerAssetAmount
- .times(primaryTakerAssetFillAmount)
- .dividedToIntegerBy(orderWithFee.takerAssetAmount);
- const takerFeePaid = orderWithFee.takerFee
- .times(primaryTakerAssetFillAmount)
- .dividedToIntegerBy(orderWithFee.takerAssetAmount);
- const makerFeePaid = orderWithFee.makerFee
- .times(primaryTakerAssetFillAmount)
- .dividedToIntegerBy(orderWithFee.takerAssetAmount);
- const totalZrxPurchased = makerAssetFilledAmount.minus(takerFeePaid);
- // Up to 1 wei worth of ZRX will be overbought per order
- const maxOverboughtZrx = new BigNumber(1)
- .times(orderWithFee.makerAssetAmount)
- .dividedToIntegerBy(orderWithFee.takerAssetAmount);
-
- expect(totalZrxPurchased).to.be.bignumber.gte(makerAssetFillAmount);
- expect(totalZrxPurchased).to.be.bignumber.lte(makerAssetFillAmount.plus(maxOverboughtZrx));
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][zrxToken.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][zrxToken.address].minus(makerAssetFilledAmount).minus(makerFeePaid),
- );
- expect(newBalances[takerAddress][zrxToken.address]).to.be.bignumber.equal(
- erc20Balances[takerAddress][zrxToken.address].plus(totalZrxPurchased),
- );
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(newBalances[forwarderContract.address][zrxToken.address]).to.be.bignumber.equal(
- erc20Balances[forwarderContract.address][zrxToken.address],
- );
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should revert if the amount of ETH sent is too low to fill the makerAssetAmount', async () => {
- const ordersWithoutFee = [orderWithoutFee];
- const feeOrders: SignedOrder[] = [];
- const makerAssetFillAmount = orderWithoutFee.makerAssetAmount.dividedToIntegerBy(2);
- const ethValue = orderWithoutFee.takerAssetAmount.dividedToIntegerBy(4);
- return expectTransactionFailedAsync(
- forwarderWrapper.marketBuyOrdersWithEthAsync(ordersWithoutFee, feeOrders, makerAssetFillAmount, {
- value: ethValue,
- from: takerAddress,
- }),
- RevertReason.CompleteFillFailed,
- );
- });
- it('should buy an ERC721 asset from a single order', async () => {
- const makerAssetId = erc721MakerAssetIds[0];
- orderWithoutFee = await orderFactory.newSignedOrderAsync({
- makerAssetAmount: new BigNumber(1),
- makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
- });
- const ordersWithoutFee = [orderWithoutFee];
- const feeOrders: SignedOrder[] = [];
- const makerAssetFillAmount = new BigNumber(1);
- const ethValue = orderWithFee.takerAssetAmount;
-
- tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(ordersWithoutFee, feeOrders, makerAssetFillAmount, {
- from: takerAddress,
- value: ethValue,
- });
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const newOwner = await erc721Token.ownerOf.callAsync(makerAssetId);
- const newBalances = await erc20Wrapper.getBalancesAsync();
-
- const primaryTakerAssetFillAmount = ethValue;
- const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
- expect(newOwner).to.be.bignumber.equal(takerAddress);
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(newBalances[forwarderContract.address][defaultMakerAssetAddress]).to.be.bignumber.equal(
- constants.ZERO_AMOUNT,
- );
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should revert if buying an ERC721 asset when later orders contain different makerAssetData', async () => {
- const makerAssetId = erc721MakerAssetIds[0];
- orderWithoutFee = await orderFactory.newSignedOrderAsync({
- makerAssetAmount: new BigNumber(1),
- makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
- });
- const differentMakerAssetDataOrder = await orderFactory.newSignedOrderAsync();
- const ordersWithoutFee = [orderWithoutFee, differentMakerAssetDataOrder];
- const feeOrders: SignedOrder[] = [];
- const makerAssetFillAmount = new BigNumber(1).plus(differentMakerAssetDataOrder.makerAssetAmount);
- const ethValue = orderWithFee.takerAssetAmount;
- return expectTransactionFailedAsync(
- forwarderWrapper.marketBuyOrdersWithEthAsync(ordersWithoutFee, feeOrders, makerAssetFillAmount, {
- value: ethValue,
- from: takerAddress,
- }),
- RevertReason.CompleteFillFailed,
- );
- });
- it('should buy an ERC721 asset and pay ZRX fees from a single fee order', async () => {
- const makerAssetId = erc721MakerAssetIds[0];
- orderWithFee = await orderFactory.newSignedOrderAsync({
- makerAssetAmount: new BigNumber(1),
- makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
- takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
- });
- const ordersWithFee = [orderWithFee];
- const feeOrders = [feeOrder];
- const makerAssetFillAmount = orderWithFee.makerAssetAmount;
- const primaryTakerAssetFillAmount = orderWithFee.takerAssetAmount;
- const feeAmount = orderWithFee.takerFee;
- const wethSpentOnFeeOrders = ForwarderWrapper.getWethForFeeOrders(feeAmount, feeOrders);
- const ethValue = primaryTakerAssetFillAmount.plus(wethSpentOnFeeOrders);
-
- tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(ordersWithFee, feeOrders, makerAssetFillAmount, {
- value: ethValue,
- from: takerAddress,
- });
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const newOwner = await erc721Token.ownerOf.callAsync(makerAssetId);
- const newBalances = await erc20Wrapper.getBalancesAsync();
-
- const totalEthSpent = ethValue.plus(gasPrice.times(tx.gasUsed));
-
- expect(newOwner).to.be.bignumber.equal(takerAddress);
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount).plus(wethSpentOnFeeOrders),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(newBalances[forwarderContract.address][defaultMakerAssetAddress]).to.be.bignumber.equal(
- constants.ZERO_AMOUNT,
- );
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should buy an ERC721 asset and pay ZRX fees from multiple fee orders', async () => {
- const makerAssetId = erc721MakerAssetIds[0];
- orderWithFee = await orderFactory.newSignedOrderAsync({
- makerAssetAmount: new BigNumber(1),
- makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
- takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
- });
- const ordersWithFee = [orderWithFee];
- const makerAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address);
- const makerAssetAmount = orderWithFee.takerFee.dividedToIntegerBy(2);
- const takerAssetAmount = feeOrder.takerAssetAmount
- .times(makerAssetAmount)
- .dividedToIntegerBy(feeOrder.makerAssetAmount);
-
- const firstFeeOrder = await orderFactory.newSignedOrderAsync({
- makerAssetData,
- makerAssetAmount,
- takerAssetAmount,
- });
- const secondFeeOrder = await orderFactory.newSignedOrderAsync({
- makerAssetData,
- makerAssetAmount,
- takerAssetAmount,
- });
- const feeOrders = [firstFeeOrder, secondFeeOrder];
-
- const makerAssetFillAmount = orderWithFee.makerAssetAmount;
- const primaryTakerAssetFillAmount = orderWithFee.takerAssetAmount;
- const feeAmount = orderWithFee.takerFee;
- const wethSpentOnFeeOrders = ForwarderWrapper.getWethForFeeOrders(feeAmount, feeOrders);
- const ethValue = primaryTakerAssetFillAmount.plus(wethSpentOnFeeOrders);
-
- tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(ordersWithFee, feeOrders, makerAssetFillAmount, {
- value: ethValue,
- from: takerAddress,
- });
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const newOwner = await erc721Token.ownerOf.callAsync(makerAssetId);
- const newBalances = await erc20Wrapper.getBalancesAsync();
-
- const totalEthSpent = ethValue.plus(gasPrice.times(tx.gasUsed));
-
- expect(newOwner).to.be.bignumber.equal(takerAddress);
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount).plus(wethSpentOnFeeOrders),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(newBalances[forwarderContract.address][defaultMakerAssetAddress]).to.be.bignumber.equal(
- constants.ZERO_AMOUNT,
- );
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('Should buy slightly greater MakerAsset when exchange rate is rounded', async () => {
- // The 0x Protocol contracts round the exchange rate in favor of the Maker.
- // In this case, the taker must round up how much they're going to spend, which
- // in turn increases the amount of MakerAsset being purchased.
- // Example:
- // The taker wants to buy 5 units of the MakerAsset at a rate of 3M/2T.
- // For every 2 units of TakerAsset, the taker will receive 3 units of MakerAsset.
- // To purchase 5 units, the taker must spend 10/3 = 3.33 units of TakerAssset.
- // However, the Taker can only spend whole units.
- // Spending floor(10/3) = 3 units will yield a profit of Floor(3*3/2) = Floor(4.5) = 4 units of MakerAsset.
- // Spending ceil(10/3) = 4 units will yield a profit of Floor(4*3/2) = 6 units of MakerAsset.
- //
- // The forwarding contract will opt for the second option, which overbuys, to ensure the taker
- // receives at least the amount of MakerAsset they requested.
- //
- // Construct test case using values from example above
- orderWithoutFee = await orderFactory.newSignedOrderAsync({
- makerAssetAmount: new BigNumber('30'),
- takerAssetAmount: new BigNumber('20'),
- makerAssetData: assetDataUtils.encodeERC20AssetData(erc20TokenA.address),
- takerAssetData: assetDataUtils.encodeERC20AssetData(weth.address),
- makerFee: new BigNumber(0),
- takerFee: new BigNumber(0),
- });
- const ordersWithoutFee = [orderWithoutFee];
- const feeOrders: SignedOrder[] = [];
- const desiredMakerAssetFillAmount = new BigNumber('5');
- const makerAssetFillAmount = new BigNumber('6');
- const ethValue = new BigNumber('4');
- // Execute test case
- tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(
- ordersWithoutFee,
- feeOrders,
- desiredMakerAssetFillAmount,
- {
- value: ethValue,
- from: takerAddress,
- },
- );
- // Fetch end balances and construct expected outputs
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const newBalances = await erc20Wrapper.getBalancesAsync();
- const primaryTakerAssetFillAmount = ethValue;
- const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
- // Validate test case
- expect(makerAssetFillAmount).to.be.bignumber.greaterThan(desiredMakerAssetFillAmount);
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
- );
- expect(newBalances[takerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[takerAddress][defaultMakerAssetAddress].plus(makerAssetFillAmount),
- );
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(newBalances[forwarderContract.address][defaultMakerAssetAddress]).to.be.bignumber.equal(
- constants.ZERO_AMOUNT,
- );
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('Should buy slightly greater MakerAsset when exchange rate is rounded, and MakerAsset is ZRX', async () => {
- // See the test case above for a detailed description of this case.
- // The difference here is that the MakerAsset is ZRX. We expect the same result as above,
- // but this tests a different code path.
- //
- // Construct test case using values from example above
- orderWithoutFee = await orderFactory.newSignedOrderAsync({
- makerAssetAmount: new BigNumber('30'),
- takerAssetAmount: new BigNumber('20'),
- makerAssetData: zrxAssetData,
- takerAssetData: assetDataUtils.encodeERC20AssetData(weth.address),
- makerFee: new BigNumber(0),
- takerFee: new BigNumber(0),
- });
- const ordersWithoutFee = [orderWithoutFee];
- const feeOrders: SignedOrder[] = [];
- const desiredMakerAssetFillAmount = new BigNumber('5');
- const makerAssetFillAmount = new BigNumber('6');
- const ethValue = new BigNumber('4');
- // Execute test case
- tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(
- ordersWithoutFee,
- feeOrders,
- desiredMakerAssetFillAmount,
- {
- value: ethValue,
- from: takerAddress,
- },
- );
- // Fetch end balances and construct expected outputs
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const newBalances = await erc20Wrapper.getBalancesAsync();
- const primaryTakerAssetFillAmount = ethValue;
- const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
- // Validate test case
- expect(makerAssetFillAmount).to.be.bignumber.greaterThan(desiredMakerAssetFillAmount);
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][zrxToken.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][zrxToken.address].minus(makerAssetFillAmount),
- );
- expect(newBalances[takerAddress][zrxToken.address]).to.be.bignumber.equal(
- erc20Balances[takerAddress][zrxToken.address].plus(makerAssetFillAmount),
- );
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('Should buy slightly greater MakerAsset when exchange rate is rounded (Regression Test)', async () => {
- // Order taken from a transaction on mainnet that failed due to a rounding error.
- orderWithoutFee = await orderFactory.newSignedOrderAsync({
- makerAssetAmount: new BigNumber('268166666666666666666'),
- takerAssetAmount: new BigNumber('219090625878836371'),
- makerAssetData: assetDataUtils.encodeERC20AssetData(erc20TokenA.address),
- takerAssetData: assetDataUtils.encodeERC20AssetData(weth.address),
- makerFee: new BigNumber(0),
- takerFee: new BigNumber(0),
- });
- const ordersWithoutFee = [orderWithoutFee];
- const feeOrders: SignedOrder[] = [];
- // The taker will receive more than the desired amount of makerAsset due to rounding
- const desiredMakerAssetFillAmount = new BigNumber('5000000000000000000');
- const ethValue = new BigNumber('4084971271824171');
- const makerAssetFillAmount = ethValue
- .times(orderWithoutFee.makerAssetAmount)
- .dividedToIntegerBy(orderWithoutFee.takerAssetAmount);
- // Execute test case
- tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(
- ordersWithoutFee,
- feeOrders,
- desiredMakerAssetFillAmount,
- {
- value: ethValue,
- from: takerAddress,
- },
- );
- // Fetch end balances and construct expected outputs
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const newBalances = await erc20Wrapper.getBalancesAsync();
- const primaryTakerAssetFillAmount = ethValue;
- const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
- // Validate test case
- expect(makerAssetFillAmount).to.be.bignumber.greaterThan(desiredMakerAssetFillAmount);
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
- );
- expect(newBalances[takerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[takerAddress][defaultMakerAssetAddress].plus(makerAssetFillAmount),
- );
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(newBalances[forwarderContract.address][defaultMakerAssetAddress]).to.be.bignumber.equal(
- constants.ZERO_AMOUNT,
- );
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('Should buy slightly greater MakerAsset when exchange rate is rounded, and MakerAsset is ZRX (Regression Test)', async () => {
- // Order taken from a transaction on mainnet that failed due to a rounding error.
- orderWithoutFee = await orderFactory.newSignedOrderAsync({
- makerAssetAmount: new BigNumber('268166666666666666666'),
- takerAssetAmount: new BigNumber('219090625878836371'),
- makerAssetData: zrxAssetData,
- takerAssetData: assetDataUtils.encodeERC20AssetData(weth.address),
- makerFee: new BigNumber(0),
- takerFee: new BigNumber(0),
- });
- const ordersWithoutFee = [orderWithoutFee];
- const feeOrders: SignedOrder[] = [];
- // The taker will receive more than the desired amount of makerAsset due to rounding
- const desiredMakerAssetFillAmount = new BigNumber('5000000000000000000');
- const ethValue = new BigNumber('4084971271824171');
- const makerAssetFillAmount = ethValue
- .times(orderWithoutFee.makerAssetAmount)
- .dividedToIntegerBy(orderWithoutFee.takerAssetAmount);
- // Execute test case
- tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(
- ordersWithoutFee,
- feeOrders,
- desiredMakerAssetFillAmount,
- {
- value: ethValue,
- from: takerAddress,
- },
- );
- // Fetch end balances and construct expected outputs
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const newBalances = await erc20Wrapper.getBalancesAsync();
- const primaryTakerAssetFillAmount = ethValue;
- const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
- // Validate test case
- expect(makerAssetFillAmount).to.be.bignumber.greaterThan(desiredMakerAssetFillAmount);
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][zrxToken.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][zrxToken.address].minus(makerAssetFillAmount),
- );
- expect(newBalances[takerAddress][zrxToken.address]).to.be.bignumber.equal(
- erc20Balances[takerAddress][zrxToken.address].plus(makerAssetFillAmount),
- );
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('Should buy correct MakerAsset when exchange rate is NOT rounded, and MakerAsset is ZRX (Regression Test)', async () => {
- // An extra unit of TakerAsset was sent to the exchange contract to account for rounding errors, in Forwarder v1.
- // Specifically, the takerFillAmount was calculated using Floor(desiredMakerAmount * exchangeRate) + 1
- // We have since changed this to be Ceil(desiredMakerAmount * exchangeRate)
- // These calculations produce different results when `desiredMakerAmount * exchangeRate` is an integer.
- //
- // This test verifies that `ceil` is sufficient:
- // Let TakerAssetAmount = MakerAssetAmount * 2
- // -> exchangeRate = TakerAssetAmount / MakerAssetAmount = (2*MakerAssetAmount)/MakerAssetAmount = 2
- // .: desiredMakerAmount * exchangeRate is an integer.
- //
- // Construct test case using values from example above
- orderWithoutFee = await orderFactory.newSignedOrderAsync({
- makerAssetAmount: new BigNumber('30'),
- takerAssetAmount: new BigNumber('60'),
- makerAssetData: zrxAssetData,
- takerAssetData: assetDataUtils.encodeERC20AssetData(weth.address),
- makerFee: new BigNumber(0),
- takerFee: new BigNumber(0),
- });
- const ordersWithoutFee = [orderWithoutFee];
- const feeOrders: SignedOrder[] = [];
- const makerAssetFillAmount = new BigNumber('5');
- const ethValue = new BigNumber('10');
- // Execute test case
- tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(ordersWithoutFee, feeOrders, makerAssetFillAmount, {
- value: ethValue,
- from: takerAddress,
- });
- // Fetch end balances and construct expected outputs
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const newBalances = await erc20Wrapper.getBalancesAsync();
- const primaryTakerAssetFillAmount = ethValue;
- const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
- // Validate test case
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][zrxToken.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][zrxToken.address].minus(makerAssetFillAmount),
- );
- expect(newBalances[takerAddress][zrxToken.address]).to.be.bignumber.equal(
- erc20Balances[takerAddress][zrxToken.address].plus(makerAssetFillAmount),
- );
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- });
- describe('marketBuyOrdersWithEth with extra fees', () => {
- it('should buy an asset and send fee to feeRecipient', async () => {
- const ordersWithoutFee = [orderWithoutFee];
- const feeOrders: SignedOrder[] = [];
- const makerAssetFillAmount = orderWithoutFee.makerAssetAmount.dividedToIntegerBy(2);
- const ethValue = orderWithoutFee.takerAssetAmount;
-
- const baseFeePercentage = 2;
- feePercentage = ForwarderWrapper.getPercentageOfValue(constants.PERCENTAGE_DENOMINATOR, baseFeePercentage);
- const feeRecipientEthBalanceBefore = await web3Wrapper.getBalanceInWeiAsync(feeRecipientAddress);
- tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(
- ordersWithoutFee,
- feeOrders,
- makerAssetFillAmount,
- {
- value: ethValue,
- from: takerAddress,
- },
- { feePercentage, feeRecipient: feeRecipientAddress },
- );
- const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
- const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
- const feeRecipientEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(feeRecipientAddress);
- const newBalances = await erc20Wrapper.getBalancesAsync();
-
- const primaryTakerAssetFillAmount = orderWithoutFee.takerAssetAmount.dividedToIntegerBy(2);
- const ethSpentOnFee = ForwarderWrapper.getPercentageOfValue(primaryTakerAssetFillAmount, baseFeePercentage);
- const totalEthSpent = primaryTakerAssetFillAmount.plus(ethSpentOnFee).plus(gasPrice.times(tx.gasUsed));
-
- expect(feeRecipientEthBalanceAfter).to.be.bignumber.equal(feeRecipientEthBalanceBefore.plus(ethSpentOnFee));
- expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
- expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
- );
- expect(newBalances[takerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
- erc20Balances[takerAddress][defaultMakerAssetAddress].plus(makerAssetFillAmount),
- );
- expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
- erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
- );
- expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(newBalances[forwarderContract.address][defaultMakerAssetAddress]).to.be.bignumber.equal(
- constants.ZERO_AMOUNT,
- );
- expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should fail if the fee is set too high', async () => {
- const ordersWithoutFee = [orderWithoutFee];
- const feeOrders: SignedOrder[] = [];
- const makerAssetFillAmount = orderWithoutFee.makerAssetAmount.dividedToIntegerBy(2);
- const ethValue = orderWithoutFee.takerAssetAmount;
-
- const baseFeePercentage = 6;
- feePercentage = ForwarderWrapper.getPercentageOfValue(constants.PERCENTAGE_DENOMINATOR, baseFeePercentage);
- await expectTransactionFailedAsync(
- forwarderWrapper.marketBuyOrdersWithEthAsync(
- ordersWithoutFee,
- feeOrders,
- makerAssetFillAmount,
- {
- value: ethValue,
- from: takerAddress,
- },
- { feePercentage, feeRecipient: feeRecipientAddress },
- ),
- RevertReason.FeePercentageTooLarge,
- );
- });
- it('should fail if there is not enough ETH remaining to pay the fee', async () => {
- const ordersWithoutFee = [orderWithoutFee];
- const feeOrders: SignedOrder[] = [];
- const makerAssetFillAmount = orderWithoutFee.makerAssetAmount.dividedToIntegerBy(2);
- const ethValue = orderWithoutFee.takerAssetAmount.dividedToIntegerBy(2);
-
- const baseFeePercentage = 2;
- feePercentage = ForwarderWrapper.getPercentageOfValue(constants.PERCENTAGE_DENOMINATOR, baseFeePercentage);
- await expectTransactionFailedAsync(
- forwarderWrapper.marketBuyOrdersWithEthAsync(
- ordersWithoutFee,
- feeOrders,
- makerAssetFillAmount,
- {
- value: ethValue,
- from: takerAddress,
- },
- { feePercentage, feeRecipient: feeRecipientAddress },
- ),
- RevertReason.InsufficientEthRemaining,
- );
- });
- });
- describe('withdrawAsset', () => {
- it('should allow owner to withdraw ERC20 tokens', async () => {
- const zrxWithdrawAmount = erc20Balances[forwarderContract.address][zrxToken.address];
- await forwarderWrapper.withdrawAssetAsync(zrxAssetData, zrxWithdrawAmount, { from: owner });
- const newBalances = await erc20Wrapper.getBalancesAsync();
- expect(newBalances[owner][zrxToken.address]).to.be.bignumber.equal(
- erc20Balances[owner][zrxToken.address].plus(zrxWithdrawAmount),
- );
- expect(newBalances[forwarderContract.address][zrxToken.address]).to.be.bignumber.equal(
- erc20Balances[forwarderContract.address][zrxToken.address].minus(zrxWithdrawAmount),
- );
- });
- it('should revert if not called by owner', async () => {
- const zrxWithdrawAmount = erc20Balances[forwarderContract.address][zrxToken.address];
- await expectTransactionFailedAsync(
- forwarderWrapper.withdrawAssetAsync(zrxAssetData, zrxWithdrawAmount, { from: makerAddress }),
- RevertReason.OnlyContractOwner,
- );
- });
- });
-});
-// tslint:disable:max-file-line-count
-// tslint:enable:no-unnecessary-type-assertion
diff --git a/contracts/core/test/extensions/order_validator.ts b/contracts/core/test/extensions/order_validator.ts
deleted file mode 100644
index 622710c98..000000000
--- a/contracts/core/test/extensions/order_validator.ts
+++ /dev/null
@@ -1,606 +0,0 @@
-import {
- chaiSetup,
- constants,
- OrderFactory,
- OrderStatus,
- provider,
- txDefaults,
- web3Wrapper,
-} from '@0x/contracts-test-utils';
-import { DummyERC20TokenContract, DummyERC721TokenContract } from '@0x/contracts-tokens';
-import { BlockchainLifecycle } from '@0x/dev-utils';
-import { assetDataUtils, orderHashUtils } from '@0x/order-utils';
-import { SignedOrder } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import * as chai from 'chai';
-import * as _ from 'lodash';
-
-import { ERC20ProxyContract } from '../../generated-wrappers/erc20_proxy';
-import { ERC721ProxyContract } from '../../generated-wrappers/erc721_proxy';
-import { ExchangeContract } from '../../generated-wrappers/exchange';
-import { OrderValidatorContract } from '../../generated-wrappers/order_validator';
-import { artifacts } from '../../src/artifacts';
-import { ERC20Wrapper } from '../utils/erc20_wrapper';
-import { ERC721Wrapper } from '../utils/erc721_wrapper';
-import { ExchangeWrapper } from '../utils/exchange_wrapper';
-
-chaiSetup.configure();
-const expect = chai.expect;
-const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
-
-describe('OrderValidator', () => {
- let makerAddress: string;
- let owner: string;
- let takerAddress: string;
- let erc20AssetData: string;
- let erc721AssetData: string;
-
- let erc20Token: DummyERC20TokenContract;
- let zrxToken: DummyERC20TokenContract;
- let erc721Token: DummyERC721TokenContract;
- let exchange: ExchangeContract;
- let orderValidator: OrderValidatorContract;
- let erc20Proxy: ERC20ProxyContract;
- let erc721Proxy: ERC721ProxyContract;
-
- let signedOrder: SignedOrder;
- let signedOrder2: SignedOrder;
- let orderFactory: OrderFactory;
-
- const tokenId = new BigNumber(123456789);
- const tokenId2 = new BigNumber(987654321);
- const ERC721_BALANCE = new BigNumber(1);
- const ERC721_ALLOWANCE = new BigNumber(1);
-
- before(async () => {
- await blockchainLifecycle.startAsync();
- });
- after(async () => {
- await blockchainLifecycle.revertAsync();
- });
-
- before(async () => {
- const accounts = await web3Wrapper.getAvailableAddressesAsync();
- const usedAddresses = ([owner, makerAddress, takerAddress] = _.slice(accounts, 0, 3));
-
- const erc20Wrapper = new ERC20Wrapper(provider, usedAddresses, owner);
- const erc721Wrapper = new ERC721Wrapper(provider, usedAddresses, owner);
-
- const numDummyErc20ToDeploy = 2;
- [erc20Token, zrxToken] = await erc20Wrapper.deployDummyTokensAsync(
- numDummyErc20ToDeploy,
- constants.DUMMY_TOKEN_DECIMALS,
- );
- erc20Proxy = await erc20Wrapper.deployProxyAsync();
-
- [erc721Token] = await erc721Wrapper.deployDummyTokensAsync();
- erc721Proxy = await erc721Wrapper.deployProxyAsync();
-
- const zrxAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address);
- exchange = await ExchangeContract.deployFrom0xArtifactAsync(
- artifacts.Exchange,
- provider,
- txDefaults,
- zrxAssetData,
- );
- const exchangeWrapper = new ExchangeWrapper(exchange, provider);
- await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, owner);
- await exchangeWrapper.registerAssetProxyAsync(erc721Proxy.address, owner);
-
- orderValidator = await OrderValidatorContract.deployFrom0xArtifactAsync(
- artifacts.OrderValidator,
- provider,
- txDefaults,
- exchange.address,
- zrxAssetData,
- );
-
- erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20Token.address);
- erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, tokenId);
- const defaultOrderParams = {
- ...constants.STATIC_ORDER_PARAMS,
- exchangeAddress: exchange.address,
- makerAddress,
- feeRecipientAddress: constants.NULL_ADDRESS,
- makerAssetData: erc20AssetData,
- takerAssetData: erc721AssetData,
- };
- const privateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)];
- orderFactory = new OrderFactory(privateKey, defaultOrderParams);
- });
-
- beforeEach(async () => {
- await blockchainLifecycle.startAsync();
- });
- afterEach(async () => {
- await blockchainLifecycle.revertAsync();
- });
-
- describe('getBalanceAndAllowance', () => {
- describe('getERC721TokenOwner', async () => {
- it('should return the null address when tokenId is not owned', async () => {
- const tokenOwner = await orderValidator.getERC721TokenOwner.callAsync(makerAddress, tokenId);
- expect(tokenOwner).to.be.equal(constants.NULL_ADDRESS);
- });
- it('should return the owner address when tokenId is owned', async () => {
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc721Token.mint.sendTransactionAsync(makerAddress, tokenId),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- const tokenOwner = await orderValidator.getERC721TokenOwner.callAsync(erc721Token.address, tokenId);
- expect(tokenOwner).to.be.equal(makerAddress);
- });
- });
- describe('ERC20 assetData', () => {
- it('should return the correct balances and allowances when both values are 0', async () => {
- const [newBalance, newAllowance] = await orderValidator.getBalanceAndAllowance.callAsync(
- makerAddress,
- erc20AssetData,
- );
- expect(constants.ZERO_AMOUNT).to.be.bignumber.equal(newBalance);
- expect(constants.ZERO_AMOUNT).to.be.bignumber.equal(newAllowance);
- });
- it('should return the correct balance and allowance when both values are non-zero', async () => {
- const balance = new BigNumber(123);
- const allowance = new BigNumber(456);
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc20Token.setBalance.sendTransactionAsync(makerAddress, balance),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc20Token.approve.sendTransactionAsync(erc20Proxy.address, allowance, {
- from: makerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- const [newBalance, newAllowance] = await orderValidator.getBalanceAndAllowance.callAsync(
- makerAddress,
- erc20AssetData,
- );
- expect(balance).to.be.bignumber.equal(newBalance);
- expect(allowance).to.be.bignumber.equal(newAllowance);
- });
- });
- describe('ERC721 assetData', () => {
- it('should return a balance of 0 when the tokenId is not owned by target', async () => {
- const [newBalance] = await orderValidator.getBalanceAndAllowance.callAsync(
- makerAddress,
- erc721AssetData,
- );
- expect(newBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should return an allowance of 0 when no approval is set', async () => {
- const [, newAllowance] = await orderValidator.getBalanceAndAllowance.callAsync(
- makerAddress,
- erc721AssetData,
- );
- expect(newAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should return a balance of 1 when the tokenId is owned by target', async () => {
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc721Token.mint.sendTransactionAsync(makerAddress, tokenId),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- const [newBalance] = await orderValidator.getBalanceAndAllowance.callAsync(
- makerAddress,
- erc721AssetData,
- );
- expect(newBalance).to.be.bignumber.equal(ERC721_BALANCE);
- });
- it('should return an allowance of 1 when ERC721Proxy is approved for all', async () => {
- const isApproved = true;
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc721Token.setApprovalForAll.sendTransactionAsync(erc721Proxy.address, isApproved, {
- from: makerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- const [, newAllowance] = await orderValidator.getBalanceAndAllowance.callAsync(
- makerAddress,
- erc721AssetData,
- );
- expect(newAllowance).to.be.bignumber.equal(ERC721_ALLOWANCE);
- });
- it('should return an allowance of 0 when ERC721Proxy is approved for specific tokenId', async () => {
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc721Token.mint.sendTransactionAsync(makerAddress, tokenId),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc721Token.approve.sendTransactionAsync(erc721Proxy.address, tokenId, {
- from: makerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- const [, newAllowance] = await orderValidator.getBalanceAndAllowance.callAsync(
- makerAddress,
- erc721AssetData,
- );
- expect(newAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- });
- });
- describe('getBalancesAndAllowances', () => {
- it('should return the correct balances and allowances when all values are 0', async () => {
- const [
- [erc20Balance, erc721Balance],
- [erc20Allowance, erc721Allowance],
- ] = await orderValidator.getBalancesAndAllowances.callAsync(makerAddress, [
- erc20AssetData,
- erc721AssetData,
- ]);
- expect(erc20Balance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(erc721Balance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(erc20Allowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(erc721Allowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should return the correct balances and allowances when balances and allowances are non-zero', async () => {
- const balance = new BigNumber(123);
- const allowance = new BigNumber(456);
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc20Token.setBalance.sendTransactionAsync(makerAddress, balance),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc20Token.approve.sendTransactionAsync(erc20Proxy.address, allowance, {
- from: makerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc721Token.mint.sendTransactionAsync(makerAddress, tokenId),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- const isApproved = true;
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc721Token.setApprovalForAll.sendTransactionAsync(erc721Proxy.address, isApproved, {
- from: makerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- const [
- [erc20Balance, erc721Balance],
- [erc20Allowance, erc721Allowance],
- ] = await orderValidator.getBalancesAndAllowances.callAsync(makerAddress, [
- erc20AssetData,
- erc721AssetData,
- ]);
- expect(erc20Balance).to.be.bignumber.equal(balance);
- expect(erc721Balance).to.be.bignumber.equal(ERC721_BALANCE);
- expect(erc20Allowance).to.be.bignumber.equal(allowance);
- expect(erc721Allowance).to.be.bignumber.equal(ERC721_ALLOWANCE);
- });
- });
- describe('getTraderInfo', () => {
- beforeEach(async () => {
- signedOrder = await orderFactory.newSignedOrderAsync();
- });
- it('should return the correct info when no balances or allowances are set', async () => {
- const traderInfo = await orderValidator.getTraderInfo.callAsync(signedOrder, takerAddress);
- expect(traderInfo.makerBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.makerAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.takerBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.takerAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.makerZrxBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.makerZrxAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.takerZrxBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.takerZrxAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should return the correct info when balances and allowances are set', async () => {
- const makerBalance = new BigNumber(123);
- const makerAllowance = new BigNumber(456);
- const makerZrxBalance = new BigNumber(789);
- const takerZrxAllowance = new BigNumber(987);
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc20Token.setBalance.sendTransactionAsync(makerAddress, makerBalance),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc20Token.approve.sendTransactionAsync(erc20Proxy.address, makerAllowance, {
- from: makerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await zrxToken.setBalance.sendTransactionAsync(makerAddress, makerZrxBalance),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await zrxToken.approve.sendTransactionAsync(erc20Proxy.address, takerZrxAllowance, {
- from: takerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc721Token.mint.sendTransactionAsync(takerAddress, tokenId),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- const isApproved = true;
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc721Token.setApprovalForAll.sendTransactionAsync(erc721Proxy.address, isApproved, {
- from: takerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- const traderInfo = await orderValidator.getTraderInfo.callAsync(signedOrder, takerAddress);
- expect(traderInfo.makerBalance).to.be.bignumber.equal(makerBalance);
- expect(traderInfo.makerAllowance).to.be.bignumber.equal(makerAllowance);
- expect(traderInfo.takerBalance).to.be.bignumber.equal(ERC721_BALANCE);
- expect(traderInfo.takerAllowance).to.be.bignumber.equal(ERC721_ALLOWANCE);
- expect(traderInfo.makerZrxBalance).to.be.bignumber.equal(makerZrxBalance);
- expect(traderInfo.makerZrxAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.takerZrxBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.takerZrxAllowance).to.be.bignumber.equal(takerZrxAllowance);
- });
- });
- describe('getTradersInfo', () => {
- beforeEach(async () => {
- signedOrder = await orderFactory.newSignedOrderAsync();
- signedOrder2 = await orderFactory.newSignedOrderAsync({
- takerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, tokenId2),
- });
- });
- it('should return the correct info when no balances or allowances have been set', async () => {
- const orders = [signedOrder, signedOrder2];
- const takers = [takerAddress, takerAddress];
- const [traderInfo1, traderInfo2] = await orderValidator.getTradersInfo.callAsync(orders, takers);
- expect(traderInfo1.makerBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.makerAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.takerBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.takerAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.makerZrxBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.makerZrxAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.takerZrxBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.takerZrxAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.makerBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.makerAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.takerBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.takerAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.makerZrxBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.makerZrxAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.takerZrxBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.takerZrxAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should return the correct info when balances and allowances are set', async () => {
- const makerBalance = new BigNumber(123);
- const makerAllowance = new BigNumber(456);
- const makerZrxBalance = new BigNumber(789);
- const takerZrxAllowance = new BigNumber(987);
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc20Token.setBalance.sendTransactionAsync(makerAddress, makerBalance),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc20Token.approve.sendTransactionAsync(erc20Proxy.address, makerAllowance, {
- from: makerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await zrxToken.setBalance.sendTransactionAsync(makerAddress, makerZrxBalance),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await zrxToken.approve.sendTransactionAsync(erc20Proxy.address, takerZrxAllowance, {
- from: takerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- const isApproved = true;
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc721Token.setApprovalForAll.sendTransactionAsync(erc721Proxy.address, isApproved, {
- from: takerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc721Token.mint.sendTransactionAsync(takerAddress, tokenId2),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- const orders = [signedOrder, signedOrder2];
- const takers = [takerAddress, takerAddress];
- const [traderInfo1, traderInfo2] = await orderValidator.getTradersInfo.callAsync(orders, takers);
-
- expect(traderInfo1.makerBalance).to.be.bignumber.equal(makerBalance);
- expect(traderInfo1.makerAllowance).to.be.bignumber.equal(makerAllowance);
- expect(traderInfo1.takerBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.takerAllowance).to.be.bignumber.equal(ERC721_ALLOWANCE);
- expect(traderInfo1.makerZrxBalance).to.be.bignumber.equal(makerZrxBalance);
- expect(traderInfo1.makerZrxAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.takerZrxBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.takerZrxAllowance).to.be.bignumber.equal(takerZrxAllowance);
- expect(traderInfo2.makerBalance).to.be.bignumber.equal(makerBalance);
- expect(traderInfo2.makerAllowance).to.be.bignumber.equal(makerAllowance);
- expect(traderInfo2.takerBalance).to.be.bignumber.equal(ERC721_BALANCE);
- expect(traderInfo2.takerAllowance).to.be.bignumber.equal(ERC721_ALLOWANCE);
- expect(traderInfo2.makerZrxBalance).to.be.bignumber.equal(makerZrxBalance);
- expect(traderInfo2.makerZrxAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.takerZrxBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.takerZrxAllowance).to.be.bignumber.equal(takerZrxAllowance);
- });
- });
- describe('getOrderAndTraderInfo', () => {
- beforeEach(async () => {
- signedOrder = await orderFactory.newSignedOrderAsync();
- });
- it('should return the correct info when no balances or allowances are set', async () => {
- const [orderInfo, traderInfo] = await orderValidator.getOrderAndTraderInfo.callAsync(
- signedOrder,
- takerAddress,
- );
- const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
- expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FILLABLE);
- expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
- expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.makerBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.makerAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.takerBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.takerAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.makerZrxBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.makerZrxAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.takerZrxBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.takerZrxAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should return the correct info when balances and allowances are set', async () => {
- const makerBalance = new BigNumber(123);
- const makerAllowance = new BigNumber(456);
- const makerZrxBalance = new BigNumber(789);
- const takerZrxAllowance = new BigNumber(987);
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc20Token.setBalance.sendTransactionAsync(makerAddress, makerBalance),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc20Token.approve.sendTransactionAsync(erc20Proxy.address, makerAllowance, {
- from: makerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await zrxToken.setBalance.sendTransactionAsync(makerAddress, makerZrxBalance),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await zrxToken.approve.sendTransactionAsync(erc20Proxy.address, takerZrxAllowance, {
- from: takerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc721Token.mint.sendTransactionAsync(takerAddress, tokenId),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- const isApproved = true;
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc721Token.setApprovalForAll.sendTransactionAsync(erc721Proxy.address, isApproved, {
- from: takerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- const [orderInfo, traderInfo] = await orderValidator.getOrderAndTraderInfo.callAsync(
- signedOrder,
- takerAddress,
- );
- const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
- expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FILLABLE);
- expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
- expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.makerBalance).to.be.bignumber.equal(makerBalance);
- expect(traderInfo.makerAllowance).to.be.bignumber.equal(makerAllowance);
- expect(traderInfo.takerBalance).to.be.bignumber.equal(ERC721_BALANCE);
- expect(traderInfo.takerAllowance).to.be.bignumber.equal(ERC721_ALLOWANCE);
- expect(traderInfo.makerZrxBalance).to.be.bignumber.equal(makerZrxBalance);
- expect(traderInfo.makerZrxAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.takerZrxBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo.takerZrxAllowance).to.be.bignumber.equal(takerZrxAllowance);
- });
- });
- describe('getOrdersAndTradersInfo', () => {
- beforeEach(async () => {
- signedOrder = await orderFactory.newSignedOrderAsync();
- signedOrder2 = await orderFactory.newSignedOrderAsync({
- takerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, tokenId2),
- });
- });
- it('should return the correct info when no balances or allowances have been set', async () => {
- const orders = [signedOrder, signedOrder2];
- const takers = [takerAddress, takerAddress];
- const [
- [orderInfo1, orderInfo2],
- [traderInfo1, traderInfo2],
- ] = await orderValidator.getOrdersAndTradersInfo.callAsync(orders, takers);
- const expectedOrderHash1 = orderHashUtils.getOrderHashHex(signedOrder);
- const expectedOrderHash2 = orderHashUtils.getOrderHashHex(signedOrder2);
- expect(orderInfo1.orderStatus).to.be.equal(OrderStatus.FILLABLE);
- expect(orderInfo1.orderHash).to.be.equal(expectedOrderHash1);
- expect(orderInfo1.orderTakerAssetFilledAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(orderInfo2.orderStatus).to.be.equal(OrderStatus.FILLABLE);
- expect(orderInfo2.orderHash).to.be.equal(expectedOrderHash2);
- expect(orderInfo2.orderTakerAssetFilledAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.makerBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.makerAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.takerBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.takerAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.makerZrxBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.makerZrxAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.takerZrxBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.takerZrxAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.makerBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.makerAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.takerBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.takerAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.makerZrxBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.makerZrxAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.takerZrxBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.takerZrxAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- });
- it('should return the correct info when balances and allowances are set', async () => {
- const makerBalance = new BigNumber(123);
- const makerAllowance = new BigNumber(456);
- const makerZrxBalance = new BigNumber(789);
- const takerZrxAllowance = new BigNumber(987);
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc20Token.setBalance.sendTransactionAsync(makerAddress, makerBalance),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc20Token.approve.sendTransactionAsync(erc20Proxy.address, makerAllowance, {
- from: makerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await zrxToken.setBalance.sendTransactionAsync(makerAddress, makerZrxBalance),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await zrxToken.approve.sendTransactionAsync(erc20Proxy.address, takerZrxAllowance, {
- from: takerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- const isApproved = true;
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc721Token.setApprovalForAll.sendTransactionAsync(erc721Proxy.address, isApproved, {
- from: takerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc721Token.mint.sendTransactionAsync(takerAddress, tokenId2),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- const orders = [signedOrder, signedOrder2];
- const takers = [takerAddress, takerAddress];
- const [
- [orderInfo1, orderInfo2],
- [traderInfo1, traderInfo2],
- ] = await orderValidator.getOrdersAndTradersInfo.callAsync(orders, takers);
- const expectedOrderHash1 = orderHashUtils.getOrderHashHex(signedOrder);
- const expectedOrderHash2 = orderHashUtils.getOrderHashHex(signedOrder2);
- expect(orderInfo1.orderStatus).to.be.equal(OrderStatus.FILLABLE);
- expect(orderInfo1.orderHash).to.be.equal(expectedOrderHash1);
- expect(orderInfo1.orderTakerAssetFilledAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(orderInfo2.orderStatus).to.be.equal(OrderStatus.FILLABLE);
- expect(orderInfo2.orderHash).to.be.equal(expectedOrderHash2);
- expect(orderInfo2.orderTakerAssetFilledAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.makerBalance).to.be.bignumber.equal(makerBalance);
- expect(traderInfo1.makerAllowance).to.be.bignumber.equal(makerAllowance);
- expect(traderInfo1.takerBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.takerAllowance).to.be.bignumber.equal(ERC721_ALLOWANCE);
- expect(traderInfo1.makerZrxBalance).to.be.bignumber.equal(makerZrxBalance);
- expect(traderInfo1.makerZrxAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.takerZrxBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo1.takerZrxAllowance).to.be.bignumber.equal(takerZrxAllowance);
- expect(traderInfo2.makerBalance).to.be.bignumber.equal(makerBalance);
- expect(traderInfo2.makerAllowance).to.be.bignumber.equal(makerAllowance);
- expect(traderInfo2.takerBalance).to.be.bignumber.equal(ERC721_BALANCE);
- expect(traderInfo2.takerAllowance).to.be.bignumber.equal(ERC721_ALLOWANCE);
- expect(traderInfo2.makerZrxBalance).to.be.bignumber.equal(makerZrxBalance);
- expect(traderInfo2.makerZrxAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.takerZrxBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
- expect(traderInfo2.takerZrxAllowance).to.be.bignumber.equal(takerZrxAllowance);
- });
- });
-});
-// tslint:disable:max-file-line-count