added more unit tests for PLP DEX sampling
This commit is contained in:
parent
8be60e2ff5
commit
9608d8fb46
@ -75,6 +75,40 @@ const samplerOperations = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
getPLPSellQuotes(
|
||||||
|
plpRegistryAddress: string,
|
||||||
|
takerToken: string,
|
||||||
|
makerToken: string,
|
||||||
|
takerFillAmounts: BigNumber[],
|
||||||
|
): BatchedOperation<BigNumber[]> {
|
||||||
|
return {
|
||||||
|
encodeCall: contract => {
|
||||||
|
return contract
|
||||||
|
.sampleSellsFromLiquidityProviderRegistry(plpRegistryAddress, takerToken, makerToken, takerFillAmounts)
|
||||||
|
.getABIEncodedTransactionData();
|
||||||
|
},
|
||||||
|
handleCallResultsAsync: async (contract, callResults) => {
|
||||||
|
return contract.getABIDecodedReturnData<BigNumber[]>('sampleSellsFromLiquidityProviderRegistry', callResults);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
getPLPBuyQuotes(
|
||||||
|
plpRegistryAddress: string,
|
||||||
|
takerToken: string,
|
||||||
|
makerToken: string,
|
||||||
|
makerFillAmounts: BigNumber[],
|
||||||
|
): BatchedOperation<BigNumber[]> {
|
||||||
|
return {
|
||||||
|
encodeCall: contract => {
|
||||||
|
return contract
|
||||||
|
.sampleBuysFromLiquidityProviderRegistry(plpRegistryAddress, takerToken, makerToken, makerFillAmounts)
|
||||||
|
.getABIEncodedTransactionData();
|
||||||
|
},
|
||||||
|
handleCallResultsAsync: async (contract, callResults) => {
|
||||||
|
return contract.getABIDecodedReturnData<BigNumber[]>('sampleBuysFromLiquidityProviderRegistry', callResults);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
getEth2DaiSellQuotes(
|
getEth2DaiSellQuotes(
|
||||||
makerToken: string,
|
makerToken: string,
|
||||||
takerToken: string,
|
takerToken: string,
|
||||||
@ -186,12 +220,12 @@ const samplerOperations = {
|
|||||||
},
|
},
|
||||||
getLiquidityProviderFromRegistry(
|
getLiquidityProviderFromRegistry(
|
||||||
registryAddress: string,
|
registryAddress: string,
|
||||||
makerToken: string,
|
|
||||||
takerToken: string,
|
takerToken: string,
|
||||||
|
makerToken: string,
|
||||||
): BatchedOperation<string> {
|
): BatchedOperation<string> {
|
||||||
return {
|
return {
|
||||||
encodeCall: contract => {
|
encodeCall: contract => {
|
||||||
return contract.getLiquidityProviderFromRegistry(registryAddress, makerToken, takerToken).getABIEncodedTransactionData()
|
return contract.getLiquidityProviderFromRegistry(registryAddress, takerToken, makerToken).getABIEncodedTransactionData();
|
||||||
},
|
},
|
||||||
handleCallResultsAsync: async (contract, callResults) => {
|
handleCallResultsAsync: async (contract, callResults) => {
|
||||||
return contract.getABIDecodedReturnData<string>('getLiquidityProviderFromRegistry', callResults);
|
return contract.getABIDecodedReturnData<string>('getLiquidityProviderFromRegistry', callResults);
|
||||||
@ -203,6 +237,7 @@ const samplerOperations = {
|
|||||||
makerToken: string,
|
makerToken: string,
|
||||||
takerToken: string,
|
takerToken: string,
|
||||||
takerFillAmounts: BigNumber[],
|
takerFillAmounts: BigNumber[],
|
||||||
|
plpRegistryAddress?: string | undefined,
|
||||||
): BatchedOperation<DexSample[][]> {
|
): BatchedOperation<DexSample[][]> {
|
||||||
const subOps = sources
|
const subOps = sources
|
||||||
.map(source => {
|
.map(source => {
|
||||||
@ -229,6 +264,13 @@ const samplerOperations = {
|
|||||||
takerFillAmounts,
|
takerFillAmounts,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
} else if (source === ERC20BridgeSource.Plp) {
|
||||||
|
if (plpRegistryAddress === undefined) {
|
||||||
|
throw new Error('Cannot sample liquidity from a PLP liquidity pool, if a registry is not provided.');
|
||||||
|
}
|
||||||
|
batchedOperation = samplerOperations.getPLPSellQuotes(
|
||||||
|
plpRegistryAddress, takerToken, makerToken, takerFillAmounts,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Unsupported sell sample source: ${source}`);
|
throw new Error(`Unsupported sell sample source: ${source}`);
|
||||||
}
|
}
|
||||||
@ -265,12 +307,20 @@ const samplerOperations = {
|
|||||||
makerToken: string,
|
makerToken: string,
|
||||||
takerToken: string,
|
takerToken: string,
|
||||||
makerFillAmounts: BigNumber[],
|
makerFillAmounts: BigNumber[],
|
||||||
|
plpRegistryAddress?: string | undefined,
|
||||||
): BatchedOperation<DexSample[][]> {
|
): BatchedOperation<DexSample[][]> {
|
||||||
const subOps = sources.map(source => {
|
const subOps = sources.map(source => {
|
||||||
if (source === ERC20BridgeSource.Eth2Dai) {
|
if (source === ERC20BridgeSource.Eth2Dai) {
|
||||||
return samplerOperations.getEth2DaiBuyQuotes(makerToken, takerToken, makerFillAmounts);
|
return samplerOperations.getEth2DaiBuyQuotes(makerToken, takerToken, makerFillAmounts);
|
||||||
} else if (source === ERC20BridgeSource.Uniswap) {
|
} else if (source === ERC20BridgeSource.Uniswap) {
|
||||||
return samplerOperations.getUniswapBuyQuotes(makerToken, takerToken, makerFillAmounts);
|
return samplerOperations.getUniswapBuyQuotes(makerToken, takerToken, makerFillAmounts);
|
||||||
|
} else if (source === ERC20BridgeSource.Plp) {
|
||||||
|
if (plpRegistryAddress === undefined) {
|
||||||
|
throw new Error('Cannot sample liquidity from a PLP liquidity pool, if a registry is not provided.');
|
||||||
|
}
|
||||||
|
return samplerOperations.getPLPBuyQuotes(
|
||||||
|
plpRegistryAddress, takerToken, makerToken, makerFillAmounts,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Unsupported buy sample source: ${source}`);
|
throw new Error(`Unsupported buy sample source: ${source}`);
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ export enum ERC20BridgeSource {
|
|||||||
CurveUsdcDai = 'Curve_USDC_DAI',
|
CurveUsdcDai = 'Curve_USDC_DAI',
|
||||||
CurveUsdcDaiUsdt = 'Curve_USDC_DAI_USDT',
|
CurveUsdcDaiUsdt = 'Curve_USDC_DAI_USDT',
|
||||||
CurveUsdcDaiUsdtTusd = 'Curve_USDC_DAI_USDT_TUSD',
|
CurveUsdcDaiUsdtTusd = 'Curve_USDC_DAI_USDT_TUSD',
|
||||||
|
Plp = 'PLP',
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal `fillData` field for `Fill` objects.
|
// Internal `fillData` field for `Fill` objects.
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import { constants, expect, getRandomFloat, getRandomInteger, randomAddress, provider, txDefaults } from '@0x/contracts-test-utils';
|
import { constants, expect, getRandomFloat, getRandomInteger, provider, randomAddress, txDefaults } from '@0x/contracts-test-utils';
|
||||||
import { assetDataUtils, generatePseudoRandomSalt } from '@0x/order-utils';
|
import { assetDataUtils, generatePseudoRandomSalt } from '@0x/order-utils';
|
||||||
import { SignedOrder } from '@0x/types';
|
import { SignedOrder } from '@0x/types';
|
||||||
import { BigNumber, hexUtils, NULL_ADDRESS } from '@0x/utils';
|
import { BigNumber, hexUtils, NULL_ADDRESS } from '@0x/utils';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import { DexOrderSampler, getSampleAmounts } from '../src/utils/market_operation_utils/sampler';
|
import { DexOrderSampler, getSampleAmounts } from '../src/utils/market_operation_utils/sampler';
|
||||||
import { ERC20BridgeSource } from '../src/utils/market_operation_utils/types';
|
import { ERC20BridgeSource, DexSample } from '../src/utils/market_operation_utils/types';
|
||||||
|
|
||||||
import { MockSamplerContract } from './utils/mock_sampler_contract';
|
import { MockSamplerContract } from './utils/mock_sampler_contract';
|
||||||
import { DummyLiquidityProviderRegistryContract, ERC20BridgeSamplerContract, IERC20BridgeSamplerContract } from '@0x/contract-wrappers';
|
import { DummyLiquidityProviderRegistryContract, ERC20BridgeSamplerContract, IERC20BridgeSamplerContract, DummyLiquidityProviderContract } from '@0x/contract-wrappers';
|
||||||
import { artifacts as erc20BridgeSamplerArtifacts } from '@0x/contracts-erc20-bridge-sampler/lib/src/artifacts';
|
import { artifacts as erc20BridgeSamplerArtifacts } from '@0x/contracts-erc20-bridge-sampler/lib/src/artifacts';
|
||||||
|
|
||||||
const CHAIN_ID = 1;
|
const CHAIN_ID = 1;
|
||||||
@ -329,31 +329,36 @@ describe('DexSampler tests', () => {
|
|||||||
expect(quotes).to.deep.eq(expectedQuotes);
|
expect(quotes).to.deep.eq(expectedQuotes);
|
||||||
});
|
});
|
||||||
|
|
||||||
it.only('getLiquidityProviderFromRegistry()', async () => {
|
describe.only('PLP Operations', () => {
|
||||||
const xAsset = randomAddress();
|
const xAsset = randomAddress();
|
||||||
const yAsset = randomAddress();
|
const yAsset = randomAddress();
|
||||||
const zAsset = randomAddress();
|
const zAsset = randomAddress();
|
||||||
const liquidityPool1 = randomAddress();
|
const liquidityPool1 = randomAddress();
|
||||||
const liquidityPool2 = randomAddress();
|
const liquidityPool2 = randomAddress();
|
||||||
|
|
||||||
// Deploy Registry
|
let registryContract: DummyLiquidityProviderRegistryContract;
|
||||||
const registryContract = await DummyLiquidityProviderRegistryContract.deployFrom0xArtifactAsync(
|
let samplerContract: ERC20BridgeSamplerContract;
|
||||||
|
beforeEach(async () => {
|
||||||
|
registryContract = await DummyLiquidityProviderRegistryContract.deployFrom0xArtifactAsync(
|
||||||
erc20BridgeSamplerArtifacts.DummyLiquidityProviderRegistry,
|
erc20BridgeSamplerArtifacts.DummyLiquidityProviderRegistry,
|
||||||
provider,
|
provider,
|
||||||
txDefaults,
|
txDefaults,
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
// Write 2 new liquidity pools
|
samplerContract = await ERC20BridgeSamplerContract.deployFrom0xArtifactAsync(
|
||||||
await registryContract.setLiquidityProviderForMarket(xAsset, yAsset, liquidityPool1).awaitTransactionSuccessAsync();
|
|
||||||
await registryContract.setLiquidityProviderForMarket(xAsset, zAsset, liquidityPool2).awaitTransactionSuccessAsync();
|
|
||||||
|
|
||||||
// Deploy the sampler
|
|
||||||
const samplerContract = await ERC20BridgeSamplerContract.deployFrom0xArtifactAsync(
|
|
||||||
erc20BridgeSamplerArtifacts.ERC20BridgeSampler,
|
erc20BridgeSamplerArtifacts.ERC20BridgeSampler,
|
||||||
provider,
|
provider,
|
||||||
txDefaults,
|
txDefaults,
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
|
});
|
||||||
|
it('getLiquidityProviderFromRegistry()', async () => {
|
||||||
|
// Deploy Registry
|
||||||
|
// Write 2 new liquidity pools
|
||||||
|
await registryContract.setLiquidityProviderForMarket(xAsset, yAsset, liquidityPool1).awaitTransactionSuccessAsync().txHashPromise;
|
||||||
|
await registryContract.setLiquidityProviderForMarket(xAsset, zAsset, liquidityPool2).awaitTransactionSuccessAsync().txHashPromise;
|
||||||
|
|
||||||
|
// Deploy the sampler
|
||||||
|
|
||||||
// Test multiple combinations: 2 pools that are present, 1 pool that is not present.
|
// Test multiple combinations: 2 pools that are present, 1 pool that is not present.
|
||||||
const dexOrderSampler = new DexOrderSampler(new IERC20BridgeSamplerContract(samplerContract.address, provider));
|
const dexOrderSampler = new DexOrderSampler(new IERC20BridgeSamplerContract(samplerContract.address, provider));
|
||||||
@ -366,6 +371,49 @@ describe('DexSampler tests', () => {
|
|||||||
expect(xzPool).to.eql(liquidityPool2);
|
expect(xzPool).to.eql(liquidityPool2);
|
||||||
expect(yzPool).to.eql(NULL_ADDRESS);
|
expect(yzPool).to.eql(NULL_ADDRESS);
|
||||||
});
|
});
|
||||||
|
it('is able to sample DEX liquidity from PLP', async () => {
|
||||||
|
const fakeLiquidityPool = await DummyLiquidityProviderContract.deployFrom0xArtifactAsync(
|
||||||
|
erc20BridgeSamplerArtifacts.DummyLiquidityProvider,
|
||||||
|
provider,
|
||||||
|
txDefaults,
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
await registryContract.setLiquidityProviderForMarket(xAsset, yAsset, fakeLiquidityPool.address).awaitTransactionSuccessAsync().txHashPromise;
|
||||||
|
|
||||||
|
const dexOrderSampler = new DexOrderSampler(new IERC20BridgeSamplerContract(samplerContract.address, provider));
|
||||||
|
const [buyQuotes, sellQuotes] = await dexOrderSampler.executeBatchAsync([
|
||||||
|
DexOrderSampler.ops.getBuyQuotes(
|
||||||
|
[ERC20BridgeSource.Plp],
|
||||||
|
xAsset,
|
||||||
|
yAsset,
|
||||||
|
[new BigNumber(10), new BigNumber(100)],
|
||||||
|
registryContract.address,
|
||||||
|
),
|
||||||
|
DexOrderSampler.ops.getSellQuotes(
|
||||||
|
[ERC20BridgeSource.Plp],
|
||||||
|
xAsset,
|
||||||
|
yAsset,
|
||||||
|
[new BigNumber(10), new BigNumber(100), new BigNumber(500)],
|
||||||
|
registryContract.address,
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
expect(buyQuotes.length).to.eql(1);
|
||||||
|
const plpBuyQuotes: DexSample[] = buyQuotes[0];
|
||||||
|
expect(plpBuyQuotes.length).to.eql(2);
|
||||||
|
for(const quote of plpBuyQuotes) {
|
||||||
|
expect(quote.source).to.bignumber.eql(ERC20BridgeSource.Plp);
|
||||||
|
expect(quote.input.plus(1)).to.bignumber.eql(quote.output);
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(sellQuotes.length).to.eql(1);
|
||||||
|
const plpSellQuotes: DexSample[] = sellQuotes[0];
|
||||||
|
expect(plpSellQuotes.length).to.eql(3);
|
||||||
|
for(const quote of plpSellQuotes) {
|
||||||
|
expect(quote.source).to.bignumber.eql(ERC20BridgeSource.Plp);
|
||||||
|
expect(quote.input.minus(1)).to.bignumber.eql(quote.output);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('batched operations', () => {
|
describe('batched operations', () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user