Reenable PLP VIP and add gasCost field to LiquidityProviderRegistry (#65)

This commit is contained in:
mzhu25 2020-12-02 17:26:48 -08:00 committed by GitHub
parent 5f1c139176
commit cc9f43ba3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 61 additions and 13 deletions

View File

@ -17,6 +17,10 @@
{
"note": "Add `unoptimizedPath` to OptimizerResult",
"pr": 62
},
{
"note": "Enable PLP VIP feature and add gasCost field to LiquidityProviderRegistry",
"pr": 65
}
]
},

View File

@ -34,7 +34,7 @@ import { getSwapMinBuyAmount } from './utils';
// tslint:disable-next-line:custom-no-magic-numbers
const MAX_UINT256 = new BigNumber(2).pow(256).minus(1);
const { NULL_ADDRESS, ZERO_AMOUNT } = constants;
const { NULL_ADDRESS, NULL_BYTES, ZERO_AMOUNT } = constants;
export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
public readonly provider: ZeroExProvider;
@ -131,6 +131,26 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
};
}
if (isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.LiquidityProvider])) {
const target = quote.orders[0].makerAddress;
return {
calldataHexString: this._exchangeProxy
.sellToLiquidityProvider(
isFromETH ? ETH_TOKEN_ADDRESS : sellToken,
isToETH ? ETH_TOKEN_ADDRESS : buyToken,
target,
NULL_ADDRESS,
sellAmount,
minBuyAmount,
NULL_BYTES,
)
.getABIEncodedTransactionData(),
ethAmount: isFromETH ? sellAmount : ZERO_AMOUNT,
toAddress: this._exchangeProxy.address,
allowanceTarget: this.contractAddresses.exchangeProxyAllowanceTarget,
};
}
// Build up the transforms.
const transforms = [];
if (isFromETH) {

View File

@ -13,6 +13,7 @@ import {
FeeSchedule,
FillData,
GetMarketOrdersOpts,
LiquidityProviderFillData,
LiquidityProviderRegistry,
MultiHopFillData,
SnowSwapFillData,
@ -445,7 +446,9 @@ export const BRIDGE_ADDRESSES_BY_CHAIN: { [chainId in ChainId]: BridgeContractAd
export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
[ERC20BridgeSource.Native]: () => 150e3,
[ERC20BridgeSource.Uniswap]: () => 90e3,
[ERC20BridgeSource.LiquidityProvider]: () => 140e3,
[ERC20BridgeSource.LiquidityProvider]: fillData => {
return (fillData as LiquidityProviderFillData).gasCost;
},
[ERC20BridgeSource.Eth2Dai]: () => 400e3,
[ERC20BridgeSource.Kyber]: () => 450e3,
[ERC20BridgeSource.Curve]: fillData => {

View File

@ -7,6 +7,6 @@ export function getLiquidityProvidersForPair(
makerToken: string,
): string[] {
return Object.entries(registry)
.filter(([, tokens]) => [makerToken, takerToken].every(t => tokens.includes(t)))
.filter(([, plp]) => [makerToken, takerToken].every(t => plp.tokens.includes(t)))
.map(([providerAddress]) => providerAddress);
}

View File

@ -235,7 +235,10 @@ export class SamplerOperations {
): SourceQuoteOperation<LiquidityProviderFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.LiquidityProvider,
fillData: { poolAddress: providerAddress },
fillData: {
poolAddress: providerAddress,
gasCost: this.liquidityProviderRegistry[providerAddress].gasCost,
},
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromLiquidityProvider,
params: [providerAddress, takerToken, makerToken, takerFillAmounts],
@ -250,7 +253,10 @@ export class SamplerOperations {
): SourceQuoteOperation<LiquidityProviderFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.LiquidityProvider,
fillData: { poolAddress: providerAddress },
fillData: {
poolAddress: providerAddress,
gasCost: this.liquidityProviderRegistry[providerAddress].gasCost,
},
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromLiquidityProvider,
params: [providerAddress, takerToken, makerToken, makerFillAmounts],

View File

@ -132,6 +132,7 @@ export interface ShellFillData extends FillData {
export interface LiquidityProviderFillData extends FillData {
poolAddress: string;
gasCost: number;
}
export interface BancorFillData extends FillData {
@ -383,7 +384,10 @@ export interface TokenAdjacencyGraph {
}
export interface LiquidityProviderRegistry {
[address: string]: [string, string];
[address: string]: {
tokens: string[];
gasCost: number;
};
}
export interface GenerateOptimizedOrdersOpts {

View File

@ -156,6 +156,7 @@ describe('DexSampler tests', () => {
const expectedMakerToken = randomAddress();
const expectedTakerToken = randomAddress();
const poolAddress = randomAddress();
const gasCost = 123;
const sampler = new MockSamplerContract({
sampleSellsFromLiquidityProvider: (providerAddress, takerToken, makerToken, _fillAmounts) => {
expect(providerAddress).to.eq(poolAddress);
@ -172,7 +173,7 @@ describe('DexSampler tests', () => {
undefined,
undefined,
undefined,
{ [poolAddress]: [expectedMakerToken, expectedTakerToken] },
{ [poolAddress]: { tokens: [expectedMakerToken, expectedTakerToken], gasCost } },
);
const [result] = await dexOrderSampler.executeAsync(
dexOrderSampler.getSellQuotes(
@ -188,7 +189,7 @@ describe('DexSampler tests', () => {
source: 'LiquidityProvider',
output: toBaseUnitAmount(1001),
input: toBaseUnitAmount(1000),
fillData: { poolAddress },
fillData: { poolAddress, gasCost },
},
],
]);
@ -198,6 +199,7 @@ describe('DexSampler tests', () => {
const expectedMakerToken = randomAddress();
const expectedTakerToken = randomAddress();
const poolAddress = randomAddress();
const gasCost = 321;
const sampler = new MockSamplerContract({
sampleBuysFromLiquidityProvider: (providerAddress, takerToken, makerToken, _fillAmounts) => {
expect(providerAddress).to.eq(poolAddress);
@ -214,7 +216,7 @@ describe('DexSampler tests', () => {
undefined,
undefined,
undefined,
{ [poolAddress]: [expectedMakerToken, expectedTakerToken] },
{ [poolAddress]: { tokens: [expectedMakerToken, expectedTakerToken], gasCost } },
);
const [result] = await dexOrderSampler.executeAsync(
dexOrderSampler.getBuyQuotes(
@ -230,7 +232,7 @@ describe('DexSampler tests', () => {
source: 'LiquidityProvider',
output: toBaseUnitAmount(999),
input: toBaseUnitAmount(1000),
fillData: { poolAddress },
fillData: { poolAddress, gasCost },
},
],
]);

View File

@ -1274,7 +1274,10 @@ describe('MarketOperationUtils tests', () => {
.poolAddress;
const rates: RatesBySource = {};
rates[ERC20BridgeSource.LiquidityProvider] = [1, 1, 1, 1];
MOCK_SAMPLER.liquidityProviderRegistry[liquidityProviderAddress] = [MAKER_TOKEN, TAKER_TOKEN];
MOCK_SAMPLER.liquidityProviderRegistry[liquidityProviderAddress] = {
tokens: [MAKER_TOKEN, TAKER_TOKEN],
gasCost: 0,
};
replaceSamplerOps({
getOrderFillableTakerAmounts: () => [constants.ZERO_AMOUNT],
getSellQuotes: createGetMultipleSellQuotesOperationFromRates(rates),
@ -1317,7 +1320,10 @@ describe('MarketOperationUtils tests', () => {
[ERC20BridgeSource.Uniswap]: [1, 1, 1, 1],
[ERC20BridgeSource.LiquidityProvider]: [0.9999, 0.9999, 0.9999, 0.9999],
};
MOCK_SAMPLER.liquidityProviderRegistry[randomAddress()] = [MAKER_TOKEN, TAKER_TOKEN];
MOCK_SAMPLER.liquidityProviderRegistry[randomAddress()] = {
tokens: [MAKER_TOKEN, TAKER_TOKEN],
gasCost: 0,
};
replaceSamplerOps({
getSellQuotes: createGetMultipleSellQuotesOperationFromRates(rates),
getMedianSellRate: createGetMedianSellRate(ETH_TO_MAKER_RATE),
@ -1736,7 +1742,10 @@ describe('MarketOperationUtils tests', () => {
[ERC20BridgeSource.Uniswap]: [1, 1, 1, 1],
[ERC20BridgeSource.LiquidityProvider]: [0.9999, 0.9999, 0.9999, 0.9999],
};
MOCK_SAMPLER.liquidityProviderRegistry[randomAddress()] = [MAKER_TOKEN, TAKER_TOKEN];
MOCK_SAMPLER.liquidityProviderRegistry[randomAddress()] = {
tokens: [MAKER_TOKEN, TAKER_TOKEN],
gasCost: 0,
};
replaceSamplerOps({
getBuyQuotes: createGetMultipleBuyQuotesOperationFromRates(rates),
getMedianSellRate: createGetMedianSellRate(ETH_TO_TAKER_RATE),