fix: [asset-swapper] disable off-chain sampling for Balancer and CREAM (#41)

* fix: [asset-swapper] disable off-chain sampling for Balancer and CREAM

* Modify  Balancer off-chain test to expect only pools

* CHANGELOG
This commit is contained in:
Jacob Evans 2020-11-19 15:00:09 +10:00 committed by GitHub
parent 927fe2b58b
commit 048d8dee60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 67 deletions

View File

@ -9,6 +9,10 @@
{ {
"note": "Return the maker/taker token decimals from the sampler as part of the `SwapQuote`", "note": "Return the maker/taker token decimals from the sampler as part of the `SwapQuote`",
"pr": 34 "pr": 34
},
{
"note": "Disable off-chain sampling for Balancer and CREAM",
"pr": 41
} }
] ]
}, },

View File

@ -5,7 +5,7 @@ import * as _ from 'lodash';
import { ERC20BridgeSamplerContract } from '../../wrappers'; import { ERC20BridgeSamplerContract } from '../../wrappers';
import { BalancerPoolsCache, computeBalancerBuyQuote, computeBalancerSellQuote } from './balancer_utils'; import { BalancerPoolsCache } from './balancer_utils';
import { BancorService } from './bancor_service'; import { BancorService } from './bancor_service';
import { LIQUIDITY_PROVIDER_REGISTRY, MAINNET_SUSHI_SWAP_ROUTER, MAX_UINT256, ZERO_AMOUNT } from './constants'; import { LIQUIDITY_PROVIDER_REGISTRY, MAINNET_SUSHI_SWAP_ROUTER, MAX_UINT256, ZERO_AMOUNT } from './constants';
import { CreamPoolsCache } from './cream_utils'; import { CreamPoolsCache } from './cream_utils';
@ -480,65 +480,74 @@ export class SamplerOperations {
public async getBalancerSellQuotesOffChainAsync( public async getBalancerSellQuotesOffChainAsync(
makerToken: string, makerToken: string,
takerToken: string, takerToken: string,
takerFillAmounts: BigNumber[], _takerFillAmounts: BigNumber[],
): Promise<Array<Array<DexSample<BalancerFillData>>>> { ): Promise<Array<Array<DexSample<BalancerFillData>>>> {
const pools = await this.balancerPoolsCache.getPoolsForPairAsync(takerToken, makerToken); // Prime the cache but do not sample off chain
return pools.map(pool => await this.balancerPoolsCache.getPoolsForPairAsync(takerToken, makerToken);
takerFillAmounts.map(amount => ({ return [];
source: ERC20BridgeSource.Balancer, // return pools.map(pool =>
output: computeBalancerSellQuote(pool, amount), // takerFillAmounts.map(amount => ({
input: amount, // source: ERC20BridgeSource.Balancer,
fillData: { poolAddress: pool.id }, // output: computeBalancerSellQuote(pool, amount),
})), // input: amount,
); // fillData: { poolAddress: pool.id },
// })),
// );
} }
public async getBalancerBuyQuotesOffChainAsync( public async getBalancerBuyQuotesOffChainAsync(
makerToken: string, makerToken: string,
takerToken: string, takerToken: string,
makerFillAmounts: BigNumber[], _makerFillAmounts: BigNumber[],
): Promise<Array<Array<DexSample<BalancerFillData>>>> { ): Promise<Array<Array<DexSample<BalancerFillData>>>> {
const pools = await this.balancerPoolsCache.getPoolsForPairAsync(takerToken, makerToken); // Prime the pools but do not sample off chain
return pools.map(pool => // Prime the cache but do not sample off chain
makerFillAmounts.map(amount => ({ await this.balancerPoolsCache.getPoolsForPairAsync(takerToken, makerToken);
source: ERC20BridgeSource.Balancer, return [];
output: computeBalancerBuyQuote(pool, amount), // return pools.map(pool =>
input: amount, // makerFillAmounts.map(amount => ({
fillData: { poolAddress: pool.id }, // source: ERC20BridgeSource.Balancer,
})), // output: computeBalancerBuyQuote(pool, amount),
); // input: amount,
// fillData: { poolAddress: pool.id },
// })),
// );
} }
public async getCreamSellQuotesOffChainAsync( public async getCreamSellQuotesOffChainAsync(
makerToken: string, makerToken: string,
takerToken: string, takerToken: string,
takerFillAmounts: BigNumber[], _takerFillAmounts: BigNumber[],
): Promise<Array<Array<DexSample<BalancerFillData>>>> { ): Promise<Array<Array<DexSample<BalancerFillData>>>> {
const pools = await this.creamPoolsCache.getPoolsForPairAsync(takerToken, makerToken); // Prime the cache but do not sample off chain
return pools.map(pool => await this.creamPoolsCache.getPoolsForPairAsync(takerToken, makerToken);
takerFillAmounts.map(amount => ({ return [];
source: ERC20BridgeSource.Cream, // return pools.map(pool =>
output: computeBalancerSellQuote(pool, amount), // takerFillAmounts.map(amount => ({
input: amount, // source: ERC20BridgeSource.Cream,
fillData: { poolAddress: pool.id }, // output: computeBalancerSellQuote(pool, amount),
})), // input: amount,
); // fillData: { poolAddress: pool.id },
// })),
// );
} }
public async getCreamBuyQuotesOffChainAsync( public async getCreamBuyQuotesOffChainAsync(
makerToken: string, makerToken: string,
takerToken: string, takerToken: string,
makerFillAmounts: BigNumber[], _makerFillAmounts: BigNumber[],
): Promise<Array<Array<DexSample<BalancerFillData>>>> { ): Promise<Array<Array<DexSample<BalancerFillData>>>> {
const pools = await this.creamPoolsCache.getPoolsForPairAsync(takerToken, makerToken); // Prime the cache but do not sample off chain
return pools.map(pool => await this.creamPoolsCache.getPoolsForPairAsync(takerToken, makerToken);
makerFillAmounts.map(amount => ({ return [];
source: ERC20BridgeSource.Cream, // return pools.map(pool =>
output: computeBalancerBuyQuote(pool, amount), // makerFillAmounts.map(amount => ({
input: amount, // source: ERC20BridgeSource.Cream,
fillData: { poolAddress: pool.id }, // output: computeBalancerBuyQuote(pool, amount),
})), // input: amount,
); // fillData: { poolAddress: pool.id },
// })),
// );
} }
public getMStableSellQuotes( public getMStableSellQuotes(

View File

@ -12,11 +12,7 @@ import { SignedOrder } from '@0x/types';
import { BigNumber, hexUtils } from '@0x/utils'; import { BigNumber, hexUtils } from '@0x/utils';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { import { BalancerPool } from '../src/utils/market_operation_utils/balancer_utils';
BalancerPool,
computeBalancerBuyQuote,
computeBalancerSellQuote,
} from '../src/utils/market_operation_utils/balancer_utils';
import { DexOrderSampler, getSampleAmounts } from '../src/utils/market_operation_utils/sampler'; import { DexOrderSampler, getSampleAmounts } from '../src/utils/market_operation_utils/sampler';
import { ERC20BridgeSource, TokenAdjacencyGraph } from '../src/utils/market_operation_utils/types'; import { ERC20BridgeSource, TokenAdjacencyGraph } from '../src/utils/market_operation_utils/types';
@ -425,7 +421,10 @@ describe('DexSampler tests', () => {
expect(quotes).to.have.lengthOf(sources.length + additionalSourceCount); expect(quotes).to.have.lengthOf(sources.length + additionalSourceCount);
expect(quotes).to.deep.eq(expectedQuotes.concat(uniswapV2ETHQuotes)); expect(quotes).to.deep.eq(expectedQuotes.concat(uniswapV2ETHQuotes));
}); });
it('getSellQuotes() uses samples from Balancer', async () => { it('getSellQuotes() fetches pools but not samples from Balancer', async () => {
// HACK
// We disabled the off-chain sampling due to incorrect data observed between
// on-chain and off-chain sampling
const expectedTakerToken = randomAddress(); const expectedTakerToken = randomAddress();
const expectedMakerToken = randomAddress(); const expectedMakerToken = randomAddress();
const expectedTakerFillAmounts = getSampleAmounts(new BigNumber(100e18), 3); const expectedTakerFillAmounts = getSampleAmounts(new BigNumber(100e18), 3);
@ -448,16 +447,7 @@ describe('DexSampler tests', () => {
expectedTakerToken, expectedTakerToken,
expectedTakerFillAmounts, expectedTakerFillAmounts,
); );
const expectedQuotes = pools.map(p => expect(quotes).to.have.lengthOf(0);
expectedTakerFillAmounts.map(a => ({
source: ERC20BridgeSource.Balancer,
input: a,
output: computeBalancerSellQuote(p, a),
fillData: { poolAddress: p.id },
})),
);
expect(quotes).to.have.lengthOf(2); // one array per pool
expect(quotes).to.deep.eq(expectedQuotes);
}); });
it('getSellQuotes() uses samples from Bancor', async () => { it('getSellQuotes() uses samples from Bancor', async () => {
const expectedTakerToken = randomAddress(); const expectedTakerToken = randomAddress();
@ -593,16 +583,7 @@ describe('DexSampler tests', () => {
expectedTakerToken, expectedTakerToken,
expectedMakerFillAmounts, expectedMakerFillAmounts,
); );
const expectedQuotes = pools.map(p => expect(quotes).to.have.lengthOf(0);
expectedMakerFillAmounts.map(a => ({
source: ERC20BridgeSource.Balancer,
input: a,
output: computeBalancerBuyQuote(p, a),
fillData: { poolAddress: p.id },
})),
);
expect(quotes).to.have.lengthOf(2); // one set per pool
expect(quotes).to.deep.eq(expectedQuotes);
}); });
}); });