feat: v4 final (#136)
* v4 FillQuoteTransformer (#104) * Update FQT to support v4 orders * `@0x/contracts-zero-ex`: Tweak FQT `@0x/contracts-zero-ex`: Drop `ERC20BridgeTransfer` event and add `PartialQuoteFill` event. * `@0x/contracts-utils`: Add `LibSafeMathV06.downcastToUint128()` * `@0x/protocol-utils`: Update transformer utils for V4 FQT * `@0x/contracts-zero-ex`: Fixing FQT tests... * `@0x/contracts-zero-ex`: rename FQT bridge event * `@0x/contracts-zero-ex`: Un-`only` tests * `@0x/migrations`: Update `BridgeAdapter` deployment * `@0x/contracts-integrations`: Delete `mtx_tests` * `@0x/protocol-utils`: Address review comments * `@0x/contracts-zero-ex`: Address review comments * `@0x/migrations`: Update migrations Co-authored-by: Michael Zhu <mchl.zhu.96@gmail.com> Co-authored-by: Lawrence Forman <me@merklejerk.com> * v4: Asset-swapper (main branch) (#113) * refactor quote_requestor * WIP v4/asset-swapper: Clean up SwapQuoter and remove @0x/orderbook * Start replacing SignedOrder everywhere * wip: new order type * wip * remove order-utils from most places * hack: Play around with VerboseX types (#119) * hack: Play around with VerboseX types * More hacks * Fix up the bridgeData encodings * Rework Orderbook return type * feat: Don't charge a protocol fee for RFQ orders WIP (#121) * fix simple build errors * simplify types a little * remove SwapQuoteCalculator: unnecessary abstraction * Fix all ./src build errors; make types consistent * export more types for use in 0x API; modify Orderbook interface * stop overriding APIOrder * feat: RFQ v4 + consolidated bridge encoders (#125) * feat: check if taker address is contract * Rework bridge data * Worst case adjustments * RFQT v4 * Future/v4 validate orders (#126) * RFQT v4 * v4 validate native orders * use default invalid signature * refactor rfqt validations in swap quoter * fix types * fix RFQT unlisted api key * remove priceAwareRFQFlag * adjust maker/taker amounts * update JSON schemas * filter zero fillable orders Co-authored-by: xianny <xianny@gmail.com> * fix type export Co-authored-by: xianny <xianny@gmail.com> * remove order-utils as much as possible * work on tests compile * Comment out quote reporter test * updated tests * restore order-utils accidental changes * some lints * Remove old fill_test * ts lint disable for now * update quote report * Re-enable quote report tests * make fill data required field * fix lint * type guards * force fillData as required * fix lint * fix naming * exports * adjust MultiBridge by slippage * cleanups (checkpoint 1) * cleanup types (checkpoint #2) * remove unused deps * `@0x/contract-addresses`: Deploy new FQT (#129) Co-authored-by: Lawrence Forman <me@merklejerk.com> * commit bump to republish * DRY up the rfqt mocker * fix: Balancer load top pools (#131) * fix: Balancer load top 250 pools * refetch top pools on an interval Co-authored-by: Jacob Evans <jacob@dekz.net> Co-authored-by: Kim Persson <kimpers@users.noreply.github.com> Co-authored-by: Lawrence Forman <lawrence@0xproject.com> Co-authored-by: Lawrence Forman <me@merklejerk.com> * Update post rebase * prettier * Remove test helpers exported in asset-swapper * Clean up from review comments * prettier * lint * recreate rfqt mocker * change merge and INVALID_SIGNATURE Co-authored-by: Lawrence Forman <lawrence@0xproject.com> Co-authored-by: Michael Zhu <mchl.zhu.96@gmail.com> Co-authored-by: Lawrence Forman <me@merklejerk.com> Co-authored-by: Xianny <8582774+xianny@users.noreply.github.com> Co-authored-by: Kim Persson <kimpers@users.noreply.github.com>
This commit is contained in:
@@ -57,4 +57,76 @@ blockchainTests.resets('BalanceChecker contract', env => {
|
||||
}
|
||||
});
|
||||
});
|
||||
describe('getMinOfBalancesOrAllowances', () => {
|
||||
it('returns the balance if the allowance can cover it', async () => {
|
||||
const makerToken = await DummyERC20TokenContract.deployFrom0xArtifactAsync(
|
||||
erc20Artifacts.DummyERC20Token,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
artifacts,
|
||||
constants.DUMMY_TOKEN_NAME,
|
||||
constants.DUMMY_TOKEN_SYMBOL,
|
||||
new BigNumber(18),
|
||||
constants.DUMMY_TOKEN_TOTAL_SUPPLY,
|
||||
);
|
||||
|
||||
const accounts = await web3Wrapper.getAvailableAddressesAsync();
|
||||
const owner = accounts[0];
|
||||
const owner2 = accounts[1];
|
||||
|
||||
const allowanceTarget = '0xdef1c0ded9bec7f1a1670819833240f027b25eff';
|
||||
|
||||
await makerToken.mint(new BigNumber(100)).awaitTransactionSuccessAsync({ from: owner });
|
||||
await makerToken.approve(allowanceTarget, new BigNumber(150)).awaitTransactionSuccessAsync({ from: owner });
|
||||
|
||||
await makerToken.mint(new BigNumber(150)).awaitTransactionSuccessAsync({ from: owner2 });
|
||||
await makerToken
|
||||
.approve(allowanceTarget, new BigNumber(200))
|
||||
.awaitTransactionSuccessAsync({ from: owner2 });
|
||||
|
||||
const testResults = await contract
|
||||
.getMinOfBalancesOrAllowances(
|
||||
[owner, owner2],
|
||||
[makerToken.address, makerToken.address],
|
||||
allowanceTarget,
|
||||
)
|
||||
.callAsync();
|
||||
|
||||
expect(testResults).to.eql([new BigNumber(100), new BigNumber(150)]);
|
||||
});
|
||||
it('returns the allowance if the allowance < balance', async () => {
|
||||
const makerToken = await DummyERC20TokenContract.deployFrom0xArtifactAsync(
|
||||
erc20Artifacts.DummyERC20Token,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
artifacts,
|
||||
constants.DUMMY_TOKEN_NAME,
|
||||
constants.DUMMY_TOKEN_SYMBOL,
|
||||
new BigNumber(18),
|
||||
constants.DUMMY_TOKEN_TOTAL_SUPPLY,
|
||||
);
|
||||
|
||||
const accounts = await web3Wrapper.getAvailableAddressesAsync();
|
||||
const owner = accounts[0];
|
||||
const owner2 = accounts[1];
|
||||
|
||||
const allowanceTarget = '0xdef1c0ded9bec7f1a1670819833240f027b25eff';
|
||||
|
||||
await makerToken.mint(new BigNumber(100)).awaitTransactionSuccessAsync({ from: owner });
|
||||
await makerToken.approve(allowanceTarget, new BigNumber(50)).awaitTransactionSuccessAsync({ from: owner });
|
||||
|
||||
await makerToken.mint(new BigNumber(100)).awaitTransactionSuccessAsync({ from: owner2 });
|
||||
await makerToken.approve(allowanceTarget, new BigNumber(75)).awaitTransactionSuccessAsync({ from: owner2 });
|
||||
|
||||
const testResults = await contract
|
||||
.getMinOfBalancesOrAllowances(
|
||||
[owner, owner2],
|
||||
[makerToken.address, makerToken.address],
|
||||
allowanceTarget,
|
||||
)
|
||||
.callAsync();
|
||||
|
||||
expect(testResults).to.eql([new BigNumber(50), new BigNumber(75)]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,11 +6,12 @@ import {
|
||||
getRandomPortion,
|
||||
randomAddress,
|
||||
} from '@0x/contracts-test-utils';
|
||||
import { Order } from '@0x/types';
|
||||
import { BigNumber, hexUtils } from '@0x/utils';
|
||||
import { SignatureType } from '@0x/protocol-utils';
|
||||
import { BigNumber, hexUtils, NULL_BYTES } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { SamplerCallResult } from '../../src/types';
|
||||
import { FillQuoteTransformerOrderType, LimitOrderFields } from '../../src';
|
||||
import { SamplerCallResult, SignedNativeOrder } from '../../src/types';
|
||||
import { artifacts } from '../artifacts';
|
||||
import { DummyLiquidityProviderContract, TestERC20BridgeSamplerContract } from '../wrappers';
|
||||
|
||||
@@ -30,7 +31,7 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
const ETH2DAI_SALT = '0xb713b61bb9bb2958a0f5d1534b21e94fc68c4c0c034b0902ed844f2f6cd1b4f7';
|
||||
const UNISWAP_BASE_SALT = '0x1d6a6a0506b0b4a554b907a4c29d9f4674e461989d9c1921feb17b26716385ab';
|
||||
const UNISWAP_V2_SALT = '0xadc7fcb33c735913b8635927e66896b356a53a912ab2ceff929e60a04b53b3c1';
|
||||
const ERC20_PROXY_ID = '0xf47261b0';
|
||||
let UNISWAP_V2_ROUTER = '';
|
||||
const INVALID_TOKEN_PAIR_ERROR = 'ERC20BridgeSampler/INVALID_TOKEN_PAIR';
|
||||
const MAKER_TOKEN = randomAddress();
|
||||
const TAKER_TOKEN = randomAddress();
|
||||
@@ -44,6 +45,7 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
env.txDefaults,
|
||||
{},
|
||||
);
|
||||
UNISWAP_V2_ROUTER = await testContract.uniswapV2Router().callAsync();
|
||||
});
|
||||
|
||||
function getPackedHash(...args: string[]): string {
|
||||
@@ -207,23 +209,19 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
return sold;
|
||||
}
|
||||
|
||||
function getDeterministicFillableTakerAssetAmount(order: Order): BigNumber {
|
||||
const hash = getPackedHash(hexUtils.leftPad(order.salt));
|
||||
return new BigNumber(hash).mod(order.takerAssetAmount);
|
||||
function getDeterministicFillableTakerAssetAmount(order: SignedNativeOrder): BigNumber {
|
||||
const hash = getPackedHash(hexUtils.leftPad(order.order.salt));
|
||||
return new BigNumber(hash).mod(order.order.takerAmount);
|
||||
}
|
||||
|
||||
function getDeterministicFillableMakerAssetAmount(order: Order): BigNumber {
|
||||
function getDeterministicFillableMakerAssetAmount(order: SignedNativeOrder): BigNumber {
|
||||
const takerAmount = getDeterministicFillableTakerAssetAmount(order);
|
||||
return order.makerAssetAmount
|
||||
return order.order.makerAmount
|
||||
.times(takerAmount)
|
||||
.div(order.takerAssetAmount)
|
||||
.div(order.order.takerAmount)
|
||||
.integerValue(BigNumber.ROUND_UP);
|
||||
}
|
||||
|
||||
function getERC20AssetData(tokenAddress: string): string {
|
||||
return hexUtils.concat(ERC20_PROXY_ID, hexUtils.leftPad(tokenAddress));
|
||||
}
|
||||
|
||||
function getSampleAmounts(tokenAddress: string, count?: number): BigNumber[] {
|
||||
const tokenDecimals = getDeterministicTokenDecimals(tokenAddress);
|
||||
const _upperLimit = getRandomPortion(getRandomInteger(1000, 50000).times(10 ** tokenDecimals));
|
||||
@@ -232,28 +230,30 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
return _.times(_count, i => d.times((i + 1) / _count).integerValue());
|
||||
}
|
||||
|
||||
function createOrder(makerToken: string, takerToken: string): Order {
|
||||
function createOrder(makerToken: string, takerToken: string): SignedNativeOrder {
|
||||
return {
|
||||
chainId: 1337,
|
||||
exchangeAddress: randomAddress(),
|
||||
makerAddress: randomAddress(),
|
||||
takerAddress: randomAddress(),
|
||||
senderAddress: randomAddress(),
|
||||
feeRecipientAddress: randomAddress(),
|
||||
makerAssetAmount: getRandomInteger(1, 1e18),
|
||||
takerAssetAmount: getRandomInteger(1, 1e18),
|
||||
makerFee: getRandomInteger(1, 1e18),
|
||||
takerFee: getRandomInteger(1, 1e18),
|
||||
makerAssetData: getERC20AssetData(makerToken),
|
||||
takerAssetData: getERC20AssetData(takerToken),
|
||||
makerFeeAssetData: getERC20AssetData(randomAddress()),
|
||||
takerFeeAssetData: getERC20AssetData(randomAddress()),
|
||||
salt: new BigNumber(hexUtils.random()),
|
||||
expirationTimeSeconds: getRandomInteger(0, 2 ** 32),
|
||||
order: {
|
||||
chainId: 1337,
|
||||
verifyingContract: randomAddress(),
|
||||
maker: randomAddress(),
|
||||
taker: randomAddress(),
|
||||
pool: NULL_BYTES,
|
||||
sender: NULL_ADDRESS,
|
||||
feeRecipient: randomAddress(),
|
||||
makerAmount: getRandomInteger(1, 1e18),
|
||||
takerAmount: getRandomInteger(1, 1e18),
|
||||
takerTokenFeeAmount: getRandomInteger(1, 1e18),
|
||||
makerToken,
|
||||
takerToken,
|
||||
salt: new BigNumber(hexUtils.random()),
|
||||
expiry: getRandomInteger(0, 2 ** 32),
|
||||
},
|
||||
signature: { v: 1, r: NULL_BYTES, s: NULL_BYTES, signatureType: SignatureType.EthSign },
|
||||
type: FillQuoteTransformerOrderType.Limit,
|
||||
};
|
||||
}
|
||||
|
||||
function createOrders(makerToken: string, takerToken: string, count?: number): Order[] {
|
||||
function createOrders(makerToken: string, takerToken: string, count?: number): SignedNativeOrder[] {
|
||||
return _.times(count || _.random(1, 16), () => createOrder(makerToken, takerToken));
|
||||
}
|
||||
|
||||
@@ -291,16 +291,20 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
describe('getOrderFillableTakerAssetAmounts()', () => {
|
||||
it('returns the expected amount for each order', async () => {
|
||||
const orders = createOrders(MAKER_TOKEN, TAKER_TOKEN);
|
||||
const signatures: string[] = _.times(orders.length, i => hexUtils.random());
|
||||
const expected = orders.map(getDeterministicFillableTakerAssetAmount);
|
||||
const actual = await testContract
|
||||
.getOrderFillableTakerAssetAmounts(orders, signatures, NULL_ADDRESS)
|
||||
.getLimitOrderFillableTakerAssetAmounts(
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
orders.map(o => o.order as LimitOrderFields),
|
||||
orders.map(o => o.signature),
|
||||
NULL_ADDRESS,
|
||||
)
|
||||
.callAsync();
|
||||
expect(actual).to.deep.eq(expected);
|
||||
});
|
||||
|
||||
it('returns empty for no orders', async () => {
|
||||
const actual = await testContract.getOrderFillableTakerAssetAmounts([], [], NULL_ADDRESS).callAsync();
|
||||
const actual = await testContract.getLimitOrderFillableTakerAssetAmounts([], [], NULL_ADDRESS).callAsync();
|
||||
expect(actual).to.deep.eq([]);
|
||||
});
|
||||
});
|
||||
@@ -308,16 +312,20 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
describe('getOrderFillableMakerAssetAmounts()', () => {
|
||||
it('returns the expected amount for each order', async () => {
|
||||
const orders = createOrders(MAKER_TOKEN, TAKER_TOKEN);
|
||||
const signatures: string[] = _.times(orders.length, i => hexUtils.random());
|
||||
const expected = orders.map(getDeterministicFillableMakerAssetAmount);
|
||||
const actual = await testContract
|
||||
.getOrderFillableMakerAssetAmounts(orders, signatures, NULL_ADDRESS)
|
||||
.getLimitOrderFillableMakerAssetAmounts(
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
orders.map(o => o.order as LimitOrderFields),
|
||||
orders.map(o => o.signature),
|
||||
NULL_ADDRESS,
|
||||
)
|
||||
.callAsync();
|
||||
expect(actual).to.deep.eq(expected);
|
||||
});
|
||||
|
||||
it('returns empty for no orders', async () => {
|
||||
const actual = await testContract.getOrderFillableMakerAssetAmounts([], [], NULL_ADDRESS).callAsync();
|
||||
const actual = await testContract.getLimitOrderFillableMakerAssetAmounts([], [], NULL_ADDRESS).callAsync();
|
||||
expect(actual).to.deep.eq([]);
|
||||
});
|
||||
});
|
||||
@@ -858,7 +866,9 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
}
|
||||
|
||||
it('can return no quotes', async () => {
|
||||
const quotes = await testContract.sampleSellsFromUniswapV2([TAKER_TOKEN, MAKER_TOKEN], []).callAsync();
|
||||
const quotes = await testContract
|
||||
.sampleSellsFromUniswapV2(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN], [])
|
||||
.callAsync();
|
||||
expect(quotes).to.deep.eq([]);
|
||||
});
|
||||
|
||||
@@ -866,7 +876,7 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
|
||||
const expectedQuotes = predictSellQuotes([TAKER_TOKEN, MAKER_TOKEN], sampleAmounts);
|
||||
const quotes = await testContract
|
||||
.sampleSellsFromUniswapV2([TAKER_TOKEN, MAKER_TOKEN], sampleAmounts)
|
||||
.sampleSellsFromUniswapV2(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN], sampleAmounts)
|
||||
.callAsync();
|
||||
expect(quotes).to.deep.eq(expectedQuotes);
|
||||
});
|
||||
@@ -876,7 +886,7 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT);
|
||||
await enableFailTriggerAsync();
|
||||
const quotes = await testContract
|
||||
.sampleSellsFromUniswapV2([TAKER_TOKEN, MAKER_TOKEN], sampleAmounts)
|
||||
.sampleSellsFromUniswapV2(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN], sampleAmounts)
|
||||
.callAsync();
|
||||
expect(quotes).to.deep.eq(expectedQuotes);
|
||||
});
|
||||
@@ -886,7 +896,11 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
|
||||
const expectedQuotes = predictSellQuotes([TAKER_TOKEN, intermediateToken, MAKER_TOKEN], sampleAmounts);
|
||||
const quotes = await testContract
|
||||
.sampleSellsFromUniswapV2([TAKER_TOKEN, intermediateToken, MAKER_TOKEN], sampleAmounts)
|
||||
.sampleSellsFromUniswapV2(
|
||||
UNISWAP_V2_ROUTER,
|
||||
[TAKER_TOKEN, intermediateToken, MAKER_TOKEN],
|
||||
sampleAmounts,
|
||||
)
|
||||
.callAsync();
|
||||
expect(quotes).to.deep.eq(expectedQuotes);
|
||||
});
|
||||
@@ -898,7 +912,9 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
}
|
||||
|
||||
it('can return no quotes', async () => {
|
||||
const quotes = await testContract.sampleBuysFromUniswapV2([TAKER_TOKEN, MAKER_TOKEN], []).callAsync();
|
||||
const quotes = await testContract
|
||||
.sampleBuysFromUniswapV2(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN], [])
|
||||
.callAsync();
|
||||
expect(quotes).to.deep.eq([]);
|
||||
});
|
||||
|
||||
@@ -906,7 +922,7 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
const sampleAmounts = getSampleAmounts(MAKER_TOKEN);
|
||||
const expectedQuotes = predictBuyQuotes([TAKER_TOKEN, MAKER_TOKEN], sampleAmounts);
|
||||
const quotes = await testContract
|
||||
.sampleBuysFromUniswapV2([TAKER_TOKEN, MAKER_TOKEN], sampleAmounts)
|
||||
.sampleBuysFromUniswapV2(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN], sampleAmounts)
|
||||
.callAsync();
|
||||
expect(quotes).to.deep.eq(expectedQuotes);
|
||||
});
|
||||
@@ -916,7 +932,7 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT);
|
||||
await enableFailTriggerAsync();
|
||||
const quotes = await testContract
|
||||
.sampleBuysFromUniswapV2([TAKER_TOKEN, MAKER_TOKEN], sampleAmounts)
|
||||
.sampleBuysFromUniswapV2(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN], sampleAmounts)
|
||||
.callAsync();
|
||||
expect(quotes).to.deep.eq(expectedQuotes);
|
||||
});
|
||||
@@ -926,7 +942,11 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
const sampleAmounts = getSampleAmounts(MAKER_TOKEN);
|
||||
const expectedQuotes = predictBuyQuotes([TAKER_TOKEN, intermediateToken, MAKER_TOKEN], sampleAmounts);
|
||||
const quotes = await testContract
|
||||
.sampleBuysFromUniswapV2([TAKER_TOKEN, intermediateToken, MAKER_TOKEN], sampleAmounts)
|
||||
.sampleBuysFromUniswapV2(
|
||||
UNISWAP_V2_ROUTER,
|
||||
[TAKER_TOKEN, intermediateToken, MAKER_TOKEN],
|
||||
sampleAmounts,
|
||||
)
|
||||
.callAsync();
|
||||
expect(quotes).to.deep.eq(expectedQuotes);
|
||||
});
|
||||
@@ -935,17 +955,21 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
describe('batchCall()', () => {
|
||||
it('can call one function', async () => {
|
||||
const orders = createOrders(MAKER_TOKEN, TAKER_TOKEN);
|
||||
const signatures: string[] = _.times(orders.length, i => hexUtils.random());
|
||||
const expected = orders.map(getDeterministicFillableTakerAssetAmount);
|
||||
const calls = [
|
||||
testContract
|
||||
.getOrderFillableTakerAssetAmounts(orders, signatures, NULL_ADDRESS)
|
||||
.getLimitOrderFillableTakerAssetAmounts(
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
orders.map(o => o.order as LimitOrderFields),
|
||||
orders.map(o => o.signature),
|
||||
NULL_ADDRESS,
|
||||
)
|
||||
.getABIEncodedTransactionData(),
|
||||
];
|
||||
const r = await testContract.batchCall(calls).callAsync();
|
||||
expect(r).to.be.length(1);
|
||||
const actual = testContract.getABIDecodedReturnData<BigNumber[]>(
|
||||
'getOrderFillableTakerAssetAmounts',
|
||||
'getLimitOrderFillableTakerAssetAmounts',
|
||||
r[0].data,
|
||||
);
|
||||
expect(actual).to.deep.eq(expected);
|
||||
@@ -954,40 +978,53 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
it('can call two functions', async () => {
|
||||
const numOrders = _.random(1, 10);
|
||||
const orders = _.times(2, () => createOrders(MAKER_TOKEN, TAKER_TOKEN, numOrders));
|
||||
const signatures: string[] = _.times(numOrders, i => hexUtils.random());
|
||||
const expecteds = [
|
||||
orders[0].map(getDeterministicFillableTakerAssetAmount),
|
||||
orders[1].map(getDeterministicFillableMakerAssetAmount),
|
||||
];
|
||||
const calls = [
|
||||
testContract
|
||||
.getOrderFillableTakerAssetAmounts(orders[0], signatures, NULL_ADDRESS)
|
||||
.getLimitOrderFillableTakerAssetAmounts(
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
orders[0].map(o => o.order as LimitOrderFields),
|
||||
orders[0].map(o => o.signature),
|
||||
NULL_ADDRESS,
|
||||
)
|
||||
.getABIEncodedTransactionData(),
|
||||
testContract
|
||||
.getOrderFillableMakerAssetAmounts(orders[1], signatures, NULL_ADDRESS)
|
||||
.getLimitOrderFillableMakerAssetAmounts(
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
orders[1].map(o => o.order as LimitOrderFields),
|
||||
orders[1].map(o => o.signature),
|
||||
NULL_ADDRESS,
|
||||
)
|
||||
.getABIEncodedTransactionData(),
|
||||
];
|
||||
const r = await testContract.batchCall(calls).callAsync();
|
||||
expect(r).to.be.length(2);
|
||||
expect(testContract.getABIDecodedReturnData('getOrderFillableTakerAssetAmounts', r[0].data)).to.deep.eq(
|
||||
expecteds[0],
|
||||
);
|
||||
expect(testContract.getABIDecodedReturnData('getOrderFillableMakerAssetAmounts', r[1].data)).to.deep.eq(
|
||||
expecteds[1],
|
||||
);
|
||||
expect(
|
||||
testContract.getABIDecodedReturnData('getLimitOrderFillableTakerAssetAmounts', r[0].data),
|
||||
).to.deep.eq(expecteds[0]);
|
||||
expect(
|
||||
testContract.getABIDecodedReturnData('getLimitOrderFillableMakerAssetAmounts', r[1].data),
|
||||
).to.deep.eq(expecteds[1]);
|
||||
});
|
||||
|
||||
it('can make recursive calls', async () => {
|
||||
const numOrders = _.random(1, 10);
|
||||
const orders = createOrders(MAKER_TOKEN, TAKER_TOKEN, numOrders);
|
||||
const signatures: string[] = _.times(numOrders, i => hexUtils.random());
|
||||
const expected = orders.map(getDeterministicFillableTakerAssetAmount);
|
||||
let r = await testContract
|
||||
.batchCall([
|
||||
testContract
|
||||
.batchCall([
|
||||
testContract
|
||||
.getOrderFillableTakerAssetAmounts(orders, signatures, NULL_ADDRESS)
|
||||
.getLimitOrderFillableTakerAssetAmounts(
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
orders.map(o => o.order as LimitOrderFields),
|
||||
orders.map(o => o.signature),
|
||||
NULL_ADDRESS,
|
||||
)
|
||||
.getABIEncodedTransactionData(),
|
||||
])
|
||||
.getABIEncodedTransactionData(),
|
||||
@@ -996,9 +1033,9 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
expect(r).to.be.length(1);
|
||||
r = testContract.getABIDecodedReturnData<SamplerCallResult[]>('batchCall', r[0].data);
|
||||
expect(r).to.be.length(1);
|
||||
expect(testContract.getABIDecodedReturnData('getOrderFillableTakerAssetAmounts', r[0].data)).to.deep.eq(
|
||||
expected,
|
||||
);
|
||||
expect(
|
||||
testContract.getABIDecodedReturnData('getLimitOrderFillableTakerAssetAmounts', r[0].data),
|
||||
).to.deep.eq(expected);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1014,12 +1051,12 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
const sellAmount = _.last(getSampleAmounts(TAKER_TOKEN))!;
|
||||
const uniswapV2FirstHopPath = [TAKER_TOKEN, INTERMEDIATE_TOKEN];
|
||||
const uniswapV2FirstHop = testContract
|
||||
.sampleSellsFromUniswapV2(uniswapV2FirstHopPath, [constants.ZERO_AMOUNT])
|
||||
.sampleSellsFromUniswapV2(UNISWAP_V2_ROUTER, uniswapV2FirstHopPath, [constants.ZERO_AMOUNT])
|
||||
.getABIEncodedTransactionData();
|
||||
|
||||
const uniswapV2SecondHopPath = [INTERMEDIATE_TOKEN, randomAddress(), MAKER_TOKEN];
|
||||
const uniswapV2SecondHop = testContract
|
||||
.sampleSellsFromUniswapV2(uniswapV2SecondHopPath, [constants.ZERO_AMOUNT])
|
||||
.sampleSellsFromUniswapV2(UNISWAP_V2_ROUTER, uniswapV2SecondHopPath, [constants.ZERO_AMOUNT])
|
||||
.getABIEncodedTransactionData();
|
||||
|
||||
const eth2DaiFirstHop = testContract
|
||||
@@ -1065,12 +1102,12 @@ blockchainTests('erc20-bridge-sampler', env => {
|
||||
const buyAmount = _.last(getSampleAmounts(MAKER_TOKEN))!;
|
||||
const uniswapV2FirstHopPath = [TAKER_TOKEN, INTERMEDIATE_TOKEN];
|
||||
const uniswapV2FirstHop = testContract
|
||||
.sampleBuysFromUniswapV2(uniswapV2FirstHopPath, [constants.ZERO_AMOUNT])
|
||||
.sampleBuysFromUniswapV2(UNISWAP_V2_ROUTER, uniswapV2FirstHopPath, [constants.ZERO_AMOUNT])
|
||||
.getABIEncodedTransactionData();
|
||||
|
||||
const uniswapV2SecondHopPath = [INTERMEDIATE_TOKEN, randomAddress(), MAKER_TOKEN];
|
||||
const uniswapV2SecondHop = testContract
|
||||
.sampleBuysFromUniswapV2(uniswapV2SecondHopPath, [constants.ZERO_AMOUNT])
|
||||
.sampleBuysFromUniswapV2(UNISWAP_V2_ROUTER, uniswapV2SecondHopPath, [constants.ZERO_AMOUNT])
|
||||
.getABIEncodedTransactionData();
|
||||
|
||||
const eth2DaiFirstHop = testContract
|
||||
|
||||
@@ -7,10 +7,12 @@ import {
|
||||
getRandomInteger,
|
||||
randomAddress,
|
||||
} from '@0x/contracts-test-utils';
|
||||
import { Order } from '@0x/types';
|
||||
import { SignatureType } from '@0x/protocol-utils';
|
||||
import { BigNumber, hexUtils } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { LimitOrderFields } from '../../src';
|
||||
import { NULL_ADDRESS } from '../../src/utils/market_operation_utils/constants';
|
||||
import { artifacts } from '../artifacts';
|
||||
import { TestNativeOrderSamplerContract } from '../wrappers';
|
||||
|
||||
@@ -18,15 +20,12 @@ const { NULL_BYTES, ZERO_AMOUNT } = constants;
|
||||
|
||||
// tslint:disable: custom-no-magic-numbers
|
||||
|
||||
blockchainTests.resets('NativeOrderSampler contract', env => {
|
||||
// TODO jacob
|
||||
blockchainTests.resets.skip('NativeOrderSampler contract', env => {
|
||||
let testContract: TestNativeOrderSamplerContract;
|
||||
let makerToken: string;
|
||||
let takerToken: string;
|
||||
let feeToken: string;
|
||||
let erc20Proxy: string;
|
||||
const ERC20_PROXY_ID = '0xf47261b0';
|
||||
const VALID_SIGNATURE = '0x01';
|
||||
const INVALID_SIGNATURE = '0x00';
|
||||
const VALID_SIGNATURE = { v: 1, r: '0x01', s: '0x01', signatureType: SignatureType.EthSign };
|
||||
|
||||
before(async () => {
|
||||
testContract = await TestNativeOrderSamplerContract.deployFrom0xArtifactAsync(
|
||||
@@ -35,9 +34,8 @@ blockchainTests.resets('NativeOrderSampler contract', env => {
|
||||
env.txDefaults,
|
||||
{},
|
||||
);
|
||||
erc20Proxy = await testContract.getAssetProxy(ERC20_PROXY_ID).callAsync();
|
||||
const NUM_TOKENS = new BigNumber(3);
|
||||
[makerToken, takerToken, feeToken] = await testContract.createTokens(NUM_TOKENS).callAsync();
|
||||
[makerToken, takerToken] = await testContract.createTokens(NUM_TOKENS).callAsync();
|
||||
await testContract.createTokens(NUM_TOKENS).awaitTransactionSuccessAsync();
|
||||
});
|
||||
|
||||
@@ -51,10 +49,10 @@ blockchainTests.resets('NativeOrderSampler contract', env => {
|
||||
orderTakerAssetFilledAmount: BigNumber;
|
||||
}
|
||||
|
||||
function getOrderInfo(order: Order): OrderInfo {
|
||||
function getOrderInfo(order: LimitOrderFields): OrderInfo {
|
||||
const hash = getPackedHash(hexUtils.leftPad(order.salt));
|
||||
const orderStatus = order.salt.mod(255).eq(0) ? 3 : 5;
|
||||
const filledAmount = order.expirationTimeSeconds;
|
||||
const filledAmount = order.expiry;
|
||||
return {
|
||||
orderStatus,
|
||||
orderHash: hash,
|
||||
@@ -70,61 +68,46 @@ blockchainTests.resets('NativeOrderSampler contract', env => {
|
||||
return new BigNumber(hexUtils.concat(hexUtils.slice(hexUtils.random(), 0, -1), '0xff'));
|
||||
}
|
||||
|
||||
function getOrderFillableTakerAmount(order: Order): BigNumber {
|
||||
return order.takerAssetAmount.minus(getOrderInfo(order).orderTakerAssetFilledAmount);
|
||||
function getLimitOrderFillableTakerAmount(order: LimitOrderFields): BigNumber {
|
||||
return order.takerAmount.minus(getOrderInfo(order).orderTakerAssetFilledAmount);
|
||||
}
|
||||
|
||||
function getERC20AssetData(tokenAddress: string): string {
|
||||
return hexUtils.concat(ERC20_PROXY_ID, hexUtils.leftPad(tokenAddress));
|
||||
}
|
||||
|
||||
function createOrder(fields: Partial<Order> = {}, filledTakerAssetAmount: BigNumber = ZERO_AMOUNT): Order {
|
||||
function createOrder(
|
||||
fields: Partial<LimitOrderFields> = {},
|
||||
filledTakerAssetAmount: BigNumber = ZERO_AMOUNT,
|
||||
): LimitOrderFields {
|
||||
return {
|
||||
chainId: 1337,
|
||||
exchangeAddress: randomAddress(),
|
||||
makerAddress: randomAddress(),
|
||||
takerAddress: randomAddress(),
|
||||
senderAddress: randomAddress(),
|
||||
feeRecipientAddress: randomAddress(),
|
||||
makerAssetAmount: getRandomInteger(1e18, 10e18),
|
||||
takerAssetAmount: getRandomInteger(1e18, 10e18),
|
||||
makerFee: getRandomInteger(1e18, 10e18),
|
||||
takerFee: getRandomInteger(1e18, 10e18),
|
||||
makerAssetData: getERC20AssetData(makerToken),
|
||||
takerAssetData: getERC20AssetData(takerToken),
|
||||
makerFeeAssetData: getERC20AssetData(feeToken),
|
||||
takerFeeAssetData: getERC20AssetData(randomAddress()),
|
||||
verifyingContract: randomAddress(),
|
||||
maker: randomAddress(),
|
||||
taker: randomAddress(),
|
||||
pool: NULL_BYTES,
|
||||
sender: NULL_ADDRESS,
|
||||
feeRecipient: randomAddress(),
|
||||
makerAmount: getRandomInteger(1, 1e18),
|
||||
takerAmount: getRandomInteger(1, 1e18),
|
||||
takerTokenFeeAmount: getRandomInteger(1, 1e18),
|
||||
makerToken,
|
||||
takerToken,
|
||||
salt: createFillableOrderSalt(),
|
||||
// Expiration time will be used to determine filled amount.
|
||||
expirationTimeSeconds: filledTakerAssetAmount,
|
||||
expiry: filledTakerAssetAmount,
|
||||
...fields,
|
||||
};
|
||||
}
|
||||
|
||||
async function fundMakerAsync(
|
||||
order: Order,
|
||||
assetData: string,
|
||||
order: LimitOrderFields,
|
||||
balanceScaling: number = 1,
|
||||
allowanceScaling: number = 1,
|
||||
): Promise<void> {
|
||||
let token;
|
||||
let amount;
|
||||
if (assetData === order.makerAssetData) {
|
||||
token = makerToken;
|
||||
amount =
|
||||
order.makerAssetData === order.makerFeeAssetData
|
||||
? order.makerAssetAmount.plus(order.makerFee)
|
||||
: order.makerAssetAmount;
|
||||
} else {
|
||||
token = feeToken;
|
||||
amount = order.makerFee;
|
||||
}
|
||||
amount = amount.times(getOrderFillableTakerAmount(order).div(BigNumber.max(1, order.takerAssetAmount)));
|
||||
const token = makerToken;
|
||||
let amount = order.makerAmount;
|
||||
amount = amount.times(getLimitOrderFillableTakerAmount(order).div(BigNumber.max(1, order.takerAmount)));
|
||||
await testContract
|
||||
.setTokenBalanceAndAllowance(
|
||||
token,
|
||||
order.makerAddress,
|
||||
erc20Proxy,
|
||||
order.maker,
|
||||
testContract.address,
|
||||
amount.times(balanceScaling).integerValue(),
|
||||
amount.times(allowanceScaling).integerValue(),
|
||||
)
|
||||
@@ -132,7 +115,7 @@ blockchainTests.resets('NativeOrderSampler contract', env => {
|
||||
}
|
||||
|
||||
describe('getTokenDecimals()', () => {
|
||||
it('correctly returns the token balances', async () => {
|
||||
it('correctly returns the token decimals', async () => {
|
||||
const newMakerToken = await DummyERC20TokenContract.deployFrom0xArtifactAsync(
|
||||
erc20Artifacts.DummyERC20Token,
|
||||
env.provider,
|
||||
@@ -154,130 +137,44 @@ blockchainTests.resets('NativeOrderSampler contract', env => {
|
||||
constants.DUMMY_TOKEN_TOTAL_SUPPLY,
|
||||
);
|
||||
const [makerDecimals, takerDecimals] = await testContract
|
||||
.getTokenDecimals(newMakerToken.address, newTakerToken.address)
|
||||
.getTokenDecimals([newMakerToken.address, newTakerToken.address])
|
||||
.callAsync();
|
||||
expect(makerDecimals.toString()).to.eql('18');
|
||||
expect(takerDecimals.toString()).to.eql('6');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOrderFillableTakerAmount()', () => {
|
||||
describe('getLimitOrderFillableTakerAmount()', () => {
|
||||
it('returns the full amount for a fully funded order', async () => {
|
||||
const order = createOrder();
|
||||
const expected = getOrderFillableTakerAmount(order);
|
||||
await fundMakerAsync(order, order.makerAssetData);
|
||||
await fundMakerAsync(order, order.makerFeeAssetData);
|
||||
const expected = getLimitOrderFillableTakerAmount(order);
|
||||
await fundMakerAsync(order);
|
||||
const actual = await testContract
|
||||
.getOrderFillableTakerAmount(order, VALID_SIGNATURE, testContract.address)
|
||||
.callAsync();
|
||||
expect(actual).to.bignumber.eq(expected);
|
||||
});
|
||||
|
||||
it('returns the full amount for a fully funded order without maker fees', async () => {
|
||||
const order = createOrder({ makerFee: ZERO_AMOUNT });
|
||||
const expected = getOrderFillableTakerAmount(order);
|
||||
await fundMakerAsync(order, order.makerAssetData);
|
||||
await fundMakerAsync(order, order.makerFeeAssetData);
|
||||
const actual = await testContract
|
||||
.getOrderFillableTakerAmount(order, VALID_SIGNATURE, testContract.address)
|
||||
.callAsync();
|
||||
expect(actual).to.bignumber.eq(expected);
|
||||
});
|
||||
|
||||
it('returns the full amount for a fully funded order without maker fee asset data', async () => {
|
||||
const order = createOrder({ makerFeeAssetData: NULL_BYTES });
|
||||
const expected = getOrderFillableTakerAmount(order);
|
||||
await fundMakerAsync(order, order.makerAssetData);
|
||||
await fundMakerAsync(order, order.makerFeeAssetData);
|
||||
const actual = await testContract
|
||||
.getOrderFillableTakerAmount(order, VALID_SIGNATURE, testContract.address)
|
||||
.callAsync();
|
||||
expect(actual).to.bignumber.eq(expected);
|
||||
});
|
||||
|
||||
it('returns the full amount for a fully funded order with maker fees denominated in the maker asset', async () => {
|
||||
const order = createOrder({ makerFeeAssetData: getERC20AssetData(makerToken) });
|
||||
const expected = getOrderFillableTakerAmount(order);
|
||||
await fundMakerAsync(order, order.makerAssetData);
|
||||
await fundMakerAsync(order, order.makerFeeAssetData);
|
||||
const actual = await testContract
|
||||
.getOrderFillableTakerAmount(order, VALID_SIGNATURE, testContract.address)
|
||||
.getLimitOrderFillableTakerAmount(order, VALID_SIGNATURE, testContract.address)
|
||||
.callAsync();
|
||||
expect(actual).to.bignumber.eq(expected);
|
||||
});
|
||||
|
||||
it('returns partial amount with insufficient maker asset balance', async () => {
|
||||
const order = createOrder();
|
||||
const expected = getOrderFillableTakerAmount(order)
|
||||
const expected = getLimitOrderFillableTakerAmount(order)
|
||||
.times(0.5)
|
||||
.integerValue(BigNumber.ROUND_DOWN);
|
||||
await fundMakerAsync(order, order.makerAssetData, 0.5);
|
||||
await fundMakerAsync(order, order.makerFeeAssetData);
|
||||
await fundMakerAsync(order, 0.5);
|
||||
const actual = await testContract
|
||||
.getOrderFillableTakerAmount(order, VALID_SIGNATURE, testContract.address)
|
||||
.getLimitOrderFillableTakerAmount(order, VALID_SIGNATURE, testContract.address)
|
||||
.callAsync();
|
||||
assertIntegerRoughlyEquals(actual, expected, 100);
|
||||
});
|
||||
|
||||
it('returns partial amount with insufficient maker asset allowance', async () => {
|
||||
const order = createOrder();
|
||||
const expected = getOrderFillableTakerAmount(order)
|
||||
const expected = getLimitOrderFillableTakerAmount(order)
|
||||
.times(0.5)
|
||||
.integerValue(BigNumber.ROUND_DOWN);
|
||||
await fundMakerAsync(order, order.makerAssetData, 1, 0.5);
|
||||
await fundMakerAsync(order, order.makerFeeAssetData);
|
||||
await fundMakerAsync(order, 1, 0.5);
|
||||
const actual = await testContract
|
||||
.getOrderFillableTakerAmount(order, VALID_SIGNATURE, testContract.address)
|
||||
.callAsync();
|
||||
assertIntegerRoughlyEquals(actual, expected, 100);
|
||||
});
|
||||
|
||||
it('returns partial amount with insufficient maker fee asset balance', async () => {
|
||||
const order = createOrder();
|
||||
const expected = getOrderFillableTakerAmount(order)
|
||||
.times(0.5)
|
||||
.integerValue(BigNumber.ROUND_DOWN);
|
||||
await fundMakerAsync(order, order.makerAssetData);
|
||||
await fundMakerAsync(order, order.makerFeeAssetData, 0.5);
|
||||
const actual = await testContract
|
||||
.getOrderFillableTakerAmount(order, VALID_SIGNATURE, testContract.address)
|
||||
.callAsync();
|
||||
assertIntegerRoughlyEquals(actual, expected, 100);
|
||||
});
|
||||
|
||||
it('returns partial amount with insufficient maker fee asset allowance', async () => {
|
||||
const order = createOrder();
|
||||
const expected = getOrderFillableTakerAmount(order)
|
||||
.times(0.5)
|
||||
.integerValue(BigNumber.ROUND_DOWN);
|
||||
await fundMakerAsync(order, order.makerAssetData);
|
||||
await fundMakerAsync(order, order.makerFeeAssetData, 1, 0.5);
|
||||
const actual = await testContract
|
||||
.getOrderFillableTakerAmount(order, VALID_SIGNATURE, testContract.address)
|
||||
.callAsync();
|
||||
assertIntegerRoughlyEquals(actual, expected, 100);
|
||||
});
|
||||
|
||||
it('returns partial amount with insufficient maker asset balance (maker asset fees)', async () => {
|
||||
const order = createOrder({ makerFeeAssetData: getERC20AssetData(makerToken) });
|
||||
const expected = getOrderFillableTakerAmount(order)
|
||||
.times(0.5)
|
||||
.integerValue(BigNumber.ROUND_DOWN);
|
||||
await fundMakerAsync(order, order.makerAssetData, 0.5);
|
||||
const actual = await testContract
|
||||
.getOrderFillableTakerAmount(order, VALID_SIGNATURE, testContract.address)
|
||||
.callAsync();
|
||||
assertIntegerRoughlyEquals(actual, expected, 100);
|
||||
});
|
||||
|
||||
it('returns partial amount with insufficient maker asset allowance (maker asset fees)', async () => {
|
||||
const order = createOrder({ makerFeeAssetData: getERC20AssetData(makerToken) });
|
||||
const expected = getOrderFillableTakerAmount(order)
|
||||
.times(0.5)
|
||||
.integerValue(BigNumber.ROUND_DOWN);
|
||||
await fundMakerAsync(order, order.makerAssetData, 1, 0.5);
|
||||
const actual = await testContract
|
||||
.getOrderFillableTakerAmount(order, VALID_SIGNATURE, testContract.address)
|
||||
.getLimitOrderFillableTakerAmount(order, VALID_SIGNATURE, testContract.address)
|
||||
.callAsync();
|
||||
assertIntegerRoughlyEquals(actual, expected, 100);
|
||||
});
|
||||
@@ -287,10 +184,9 @@ blockchainTests.resets('NativeOrderSampler contract', env => {
|
||||
...createOrder(),
|
||||
salt: createUnfillableOrderSalt(),
|
||||
};
|
||||
await fundMakerAsync(order, order.makerAssetData);
|
||||
await fundMakerAsync(order, order.makerFeeAssetData);
|
||||
await fundMakerAsync(order);
|
||||
const fillableTakerAmount = await testContract
|
||||
.getOrderFillableTakerAmount(order, VALID_SIGNATURE, testContract.address)
|
||||
.getLimitOrderFillableTakerAmount(order, VALID_SIGNATURE, testContract.address)
|
||||
.callAsync();
|
||||
expect(fillableTakerAmount).to.bignumber.eq(ZERO_AMOUNT);
|
||||
});
|
||||
@@ -298,12 +194,11 @@ blockchainTests.resets('NativeOrderSampler contract', env => {
|
||||
it('returns zero for an order with zero maker asset amount', async () => {
|
||||
const order = {
|
||||
...createOrder(),
|
||||
makerAssetAmount: ZERO_AMOUNT,
|
||||
makerAmount: ZERO_AMOUNT,
|
||||
};
|
||||
await fundMakerAsync(order, order.makerAssetData);
|
||||
await fundMakerAsync(order, order.makerFeeAssetData);
|
||||
await fundMakerAsync(order);
|
||||
const fillableTakerAmount = await testContract
|
||||
.getOrderFillableTakerAmount(order, VALID_SIGNATURE, testContract.address)
|
||||
.getLimitOrderFillableTakerAmount(order, VALID_SIGNATURE, testContract.address)
|
||||
.callAsync();
|
||||
expect(fillableTakerAmount).to.bignumber.eq(ZERO_AMOUNT);
|
||||
});
|
||||
@@ -311,32 +206,24 @@ blockchainTests.resets('NativeOrderSampler contract', env => {
|
||||
it('returns zero for an order with zero taker asset amount', async () => {
|
||||
const order = {
|
||||
...createOrder(),
|
||||
takerAssetAmount: ZERO_AMOUNT,
|
||||
takerAmount: ZERO_AMOUNT,
|
||||
};
|
||||
await fundMakerAsync(order, order.makerAssetData);
|
||||
await fundMakerAsync(order, order.makerFeeAssetData);
|
||||
await fundMakerAsync(order);
|
||||
const fillableTakerAmount = await testContract
|
||||
.getOrderFillableTakerAmount(order, VALID_SIGNATURE, testContract.address)
|
||||
.getLimitOrderFillableTakerAmount(order, VALID_SIGNATURE, testContract.address)
|
||||
.callAsync();
|
||||
expect(fillableTakerAmount).to.bignumber.eq(ZERO_AMOUNT);
|
||||
});
|
||||
|
||||
it('returns zero for an order with an empty signature', async () => {
|
||||
const order = createOrder();
|
||||
await fundMakerAsync(order, order.makerAssetData);
|
||||
await fundMakerAsync(order, order.makerFeeAssetData);
|
||||
await fundMakerAsync(order);
|
||||
const fillableTakerAmount = await testContract
|
||||
.getOrderFillableTakerAmount(order, NULL_BYTES, testContract.address)
|
||||
.callAsync();
|
||||
expect(fillableTakerAmount).to.bignumber.eq(ZERO_AMOUNT);
|
||||
});
|
||||
|
||||
it('returns zero for an order with an invalid signature', async () => {
|
||||
const order = createOrder();
|
||||
await fundMakerAsync(order, order.makerAssetData);
|
||||
await fundMakerAsync(order, order.makerFeeAssetData);
|
||||
const fillableTakerAmount = await testContract
|
||||
.getOrderFillableTakerAmount(order, INVALID_SIGNATURE, testContract.address)
|
||||
.getLimitOrderFillableTakerAmount(
|
||||
order,
|
||||
{ ...VALID_SIGNATURE, r: NULL_BYTES, s: NULL_BYTES },
|
||||
testContract.address,
|
||||
)
|
||||
.callAsync();
|
||||
expect(fillableTakerAmount).to.bignumber.eq(ZERO_AMOUNT);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user