aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contracts/test/combinatorial_tests.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/contracts/test/combinatorial_tests.ts')
-rw-r--r--packages/contracts/test/combinatorial_tests.ts266
1 files changed, 266 insertions, 0 deletions
diff --git a/packages/contracts/test/combinatorial_tests.ts b/packages/contracts/test/combinatorial_tests.ts
new file mode 100644
index 000000000..7a118f6ac
--- /dev/null
+++ b/packages/contracts/test/combinatorial_tests.ts
@@ -0,0 +1,266 @@
+import { BlockchainLifecycle } from '@0xproject/dev-utils';
+import { assetProxyUtils, crypto, orderHashUtils, OrderStateUtils } from '@0xproject/order-utils';
+import { AssetProxyId, SignatureType, SignedOrder } from '@0xproject/types';
+import { BigNumber } from '@0xproject/utils';
+import { Web3Wrapper } from '@0xproject/web3-wrapper';
+import * as chai from 'chai';
+import { LogWithDecodedArgs } from 'ethereum-types';
+import ethUtil = require('ethereumjs-util');
+import 'make-promises-safe';
+
+import { DummyERC20TokenContract } from '../src/contract_wrappers/generated/dummy_e_r_c20_token';
+import { DummyERC721TokenContract } from '../src/contract_wrappers/generated/dummy_e_r_c721_token';
+import { ERC20ProxyContract } from '../src/contract_wrappers/generated/e_r_c20_proxy';
+import { ERC721ProxyContract } from '../src/contract_wrappers/generated/e_r_c721_proxy';
+import {
+ CancelContractEventArgs,
+ ExchangeContract,
+ FillContractEventArgs,
+} from '../src/contract_wrappers/generated/exchange';
+import { artifacts } from '../src/utils/artifacts';
+import { chaiSetup } from '../src/utils/chai_setup';
+import { constants } from '../src/utils/constants';
+import { ERC20Wrapper } from '../src/utils/erc20_wrapper';
+import { ERC721Wrapper } from '../src/utils/erc721_wrapper';
+import { ExchangeWrapper } from '../src/utils/exchange_wrapper';
+import { NewOrderFactory } from '../src/utils/new_order_factory';
+import { OrderInfoUtils } from '../src/utils/order_info_utils';
+import { orderUtils } from '../src/utils/order_utils';
+import { signingUtils } from '../src/utils/signing_utils';
+import {
+ AssetDataScenario,
+ ContractName,
+ ERC20BalancesByOwner,
+ ExpirationTimeSecondsScenario,
+ FeeRecipientAddressScenario,
+ OrderAmountScenario,
+ OrderStatus,
+} from '../src/utils/types';
+
+import { provider, txDefaults, web3Wrapper } from '../src/utils/web3_wrapper';
+
+chaiSetup.configure();
+const expect = chai.expect;
+const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
+
+describe('Combinatorial tests', () => {
+ let newOrderFactory: NewOrderFactory;
+ let usedAddresses: string[];
+
+ let makerAddress: string;
+ let owner: string;
+ let takerAddress: string;
+ let feeRecipientAddress: string;
+
+ let erc20EighteenDecimalTokenA: DummyERC20TokenContract;
+ let erc20EighteenDecimalTokenB: DummyERC20TokenContract;
+ let erc20FiveDecimalTokenA: DummyERC20TokenContract;
+ let erc20FiveDecimalTokenB: DummyERC20TokenContract;
+ let zrxToken: DummyERC20TokenContract;
+ let erc721Token: DummyERC721TokenContract;
+ let exchange: ExchangeContract;
+ let erc20Proxy: ERC20ProxyContract;
+ let erc721Proxy: ERC721ProxyContract;
+
+ let erc20Balances: ERC20BalancesByOwner;
+ let exchangeWrapper: ExchangeWrapper;
+ let erc20Wrapper: ERC20Wrapper;
+ let erc721Wrapper: ERC721Wrapper;
+
+ let erc721MakerAssetIds: BigNumber[];
+ let erc721TakerAssetIds: BigNumber[];
+
+ let defaultMakerAssetAddress: string;
+ let defaultTakerAssetAddress: string;
+
+ before(async () => {
+ await blockchainLifecycle.startAsync();
+ });
+ after(async () => {
+ await blockchainLifecycle.revertAsync();
+ });
+ before(async () => {
+ const accounts = await web3Wrapper.getAvailableAddressesAsync();
+ usedAddresses = [owner, makerAddress, takerAddress, feeRecipientAddress] = accounts;
+
+ erc20Wrapper = new ERC20Wrapper(provider, usedAddresses, owner);
+ erc721Wrapper = new ERC721Wrapper(provider, usedAddresses, owner);
+
+ const erc20EighteenDecimalTokenCount = 3;
+ const eighteenDecimals = new BigNumber(18);
+ [erc20EighteenDecimalTokenA, erc20EighteenDecimalTokenB, zrxToken] = await erc20Wrapper.deployDummyTokensAsync(
+ erc20EighteenDecimalTokenCount,
+ eighteenDecimals,
+ );
+
+ const erc20FiveDecimalTokenCount = 2;
+ const fiveDecimals = new BigNumber(18);
+ [erc20FiveDecimalTokenA, erc20FiveDecimalTokenB] = await erc20Wrapper.deployDummyTokensAsync(
+ erc20FiveDecimalTokenCount,
+ fiveDecimals,
+ );
+ erc20Proxy = await erc20Wrapper.deployProxyAsync();
+ await erc20Wrapper.setBalancesAndAllowancesAsync();
+
+ [erc721Token] = await erc721Wrapper.deployDummyTokensAsync();
+ erc721Proxy = await erc721Wrapper.deployProxyAsync();
+ await erc721Wrapper.setBalancesAndAllowancesAsync();
+ const erc721Balances = await erc721Wrapper.getBalancesAsync();
+ erc721MakerAssetIds = erc721Balances[makerAddress][erc721Token.address];
+ erc721TakerAssetIds = erc721Balances[takerAddress][erc721Token.address];
+
+ exchange = await ExchangeContract.deployFrom0xArtifactAsync(
+ artifacts.Exchange,
+ provider,
+ txDefaults,
+ assetProxyUtils.encodeERC20ProxyData(zrxToken.address),
+ );
+ exchangeWrapper = new ExchangeWrapper(exchange, provider);
+ await exchangeWrapper.registerAssetProxyAsync(AssetProxyId.ERC20, erc20Proxy.address, owner);
+ await exchangeWrapper.registerAssetProxyAsync(AssetProxyId.ERC721, erc721Proxy.address, owner);
+
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, {
+ from: owner,
+ }),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, {
+ from: owner,
+ }),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+
+ defaultMakerAssetAddress = erc20EighteenDecimalTokenA.address;
+ defaultTakerAssetAddress = erc20EighteenDecimalTokenB.address;
+
+ newOrderFactory = new NewOrderFactory(
+ usedAddresses,
+ zrxToken.address,
+ [erc20EighteenDecimalTokenA.address, erc20EighteenDecimalTokenB.address],
+ [erc20FiveDecimalTokenA.address, erc20FiveDecimalTokenB.address],
+ erc721Token,
+ erc721Balances,
+ exchange.address,
+ );
+ });
+ beforeEach(async () => {
+ await blockchainLifecycle.startAsync();
+ });
+ afterEach(async () => {
+ await blockchainLifecycle.revertAsync();
+ });
+ describe.only('Fill order', () => {
+ beforeEach(async () => {
+ erc20Balances = await erc20Wrapper.getBalancesAsync();
+ });
+ it('should transfer the correct amounts when makerAssetAmount === takerAssetAmount', async () => {
+ const order = newOrderFactory.generateOrder(
+ FeeRecipientAddressScenario.EthUserAddress,
+ OrderAmountScenario.NonZero,
+ OrderAmountScenario.NonZero,
+ OrderAmountScenario.Zero,
+ OrderAmountScenario.Zero,
+ ExpirationTimeSecondsScenario.InFuture,
+ AssetDataScenario.ERC20NonZRXEighteenDecimals,
+ AssetDataScenario.ERC20NonZRXEighteenDecimals,
+ );
+
+ // TODO: Permute signature types
+
+ // TODO: Sign order (for now simply ECSign)
+ const orderHashBuff = orderHashUtils.getOrderHashBuff(order);
+ const privateKey = constants.TESTRPC_PRIVATE_KEYS[usedAddresses.indexOf(makerAddress)];
+ const signature = signingUtils.signMessage(orderHashBuff, privateKey, SignatureType.EthSign);
+ const signedOrder = {
+ ...order,
+ signature: `0x${signature.toString('hex')}`,
+ };
+ console.log('signedOrder', signedOrder);
+
+ // TODO: Get orderRelevantState
+ const orderInfoUtils = new OrderInfoUtils(exchange, erc20Wrapper, zrxToken.address);
+ // 1. How much of this order can I fill?
+ const fillableTakerAssetAmount = await orderInfoUtils.getFillableTakerAssetAmountAsync(
+ signedOrder,
+ takerAddress,
+ );
+ console.log('fillableTakerAssetAmount', fillableTakerAssetAmount);
+
+ // TODO: Decide how much to fill (all, some)
+ const takerFillAmount = fillableTakerAssetAmount.div(2); // some for now
+
+ // 2. If I fill it by X, what are the resulting balances/allowances/filled amounts expected?
+ // NOTE: we can't use orderStateUtils for this :( We need to do this ourselves.
+
+ // This doesn't include taker balance/allowance checks...
+ /*
+ Inputs:
+ - signedOrder
+ - takerAddress
+ Outputs:
+ - Check fillable amount
+ - maker token balance & allowance
+ - maker ZRX balance & allowance
+ - taker token balance & allowance
+ - taker ZRX balance & allowance
+ Test:
+ - If fillable >= fillAmount:
+ - check that filled by fillAmount
+ - check makerBalance
+ */
+
+ // signedOrder = orderFactory.newSignedOrder({
+ // makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
+ // takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
+ // }); );
+ //
+ // const takerAssetFilledAmountBefore = await exchangeWrapper.getTakerAssetFilledAmountAsync(
+ // orderHashUtils.getOrderHashHex(signedOrder),
+ // );
+ // expect(takerAssetFilledAmountBefore).to.be.bignumber.equal(0);
+ //
+ // const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
+ // await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
+ //
+ // const makerAmountBoughtAfter = await exchangeWrapper.getTakerAssetFilledAmountAsync(
+ // orderHashUtils.getOrderHashHex(signedOrder),
+ // );
+ // expect(makerAmountBoughtAfter).to.be.bignumber.equal(takerAssetFillAmount);
+ //
+ // const newBalances = await erc20Wrapper.getBalancesAsync();
+ //
+ // const makerAssetFilledAmount = takerAssetFillAmount
+ // .times(signedOrder.makerAssetAmount)
+ // .dividedToIntegerBy(signedOrder.takerAssetAmount);
+ // const makerFeePaid = signedOrder.makerFee
+ // .times(makerAssetFilledAmount)
+ // .dividedToIntegerBy(signedOrder.makerAssetAmount);
+ // const takerFeePaid = signedOrder.takerFee
+ // .times(makerAssetFilledAmount)
+ // .dividedToIntegerBy(signedOrder.makerAssetAmount);
+ // expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
+ // erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFilledAmount),
+ // );
+ // expect(newBalances[makerAddress][defaultTakerAssetAddress]).to.be.bignumber.equal(
+ // erc20Balances[makerAddress][defaultTakerAssetAddress].add(takerAssetFillAmount),
+ // );
+ // expect(newBalances[makerAddress][zrxToken.address]).to.be.bignumber.equal(
+ // erc20Balances[makerAddress][zrxToken.address].minus(makerFeePaid),
+ // );
+ // expect(newBalances[takerAddress][defaultTakerAssetAddress]).to.be.bignumber.equal(
+ // erc20Balances[takerAddress][defaultTakerAssetAddress].minus(takerAssetFillAmount),
+ // );
+ // expect(newBalances[takerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
+ // erc20Balances[takerAddress][defaultMakerAssetAddress].add(makerAssetFilledAmount),
+ // );
+ // expect(newBalances[takerAddress][zrxToken.address]).to.be.bignumber.equal(
+ // erc20Balances[takerAddress][zrxToken.address].minus(takerFeePaid),
+ // );
+ // expect(newBalances[feeRecipientAddress][zrxToken.address]).to.be.bignumber.equal(
+ // erc20Balances[feeRecipientAddress][zrxToken.address].add(makerFeePaid.add(takerFeePaid)),
+ // );
+ });
+ });
+});