Skip to content

Commit

Permalink
Merge pull request #33 from violetprotocol/feat/DADZ-355
Browse files Browse the repository at this point in the history
[DADZ-355] Enable routing to accept tokens to be excluded when finding a suitable route
  • Loading branch information
0xpApaSmURf authored Oct 12, 2023
2 parents 489837d + dc1d425 commit 1be9fc9
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 4 deletions.
11 changes: 11 additions & 0 deletions cli/commands/quote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export class Quote extends BaseCommand {
required: false,
default: false,
}),
excludeTokens: flags.string({ required: false }),
simulate: flags.boolean({ required: false, default: false }),
};

Expand Down Expand Up @@ -67,6 +68,7 @@ export class Quote extends BaseCommand {
protocols: protocolsStr,
forceCrossProtocol,
forceMixedRoutes,
excludeTokens,
simulate,
} = flags;

Expand All @@ -87,6 +89,13 @@ export class Quote extends BaseCommand {
}
}

let excludeTokensFromRoute: string[] | undefined = undefined;
if (excludeTokens)
excludeTokensFromRoute = excludeTokens
.toLowerCase()
.replace(' ', '')
.split(',');

const chainId = ID_TO_CHAIN_ID(chainIdNumb);

const log = this.logger;
Expand Down Expand Up @@ -142,6 +151,7 @@ export class Quote extends BaseCommand {
protocols,
forceCrossProtocol,
forceMixedRoutes,
excludeTokens: excludeTokensFromRoute,
}
);
} else {
Expand Down Expand Up @@ -176,6 +186,7 @@ export class Quote extends BaseCommand {
protocols,
forceCrossProtocol,
forceMixedRoutes,
excludeTokens: excludeTokensFromRoute,
}
);
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@violetprotocol/mauve-smart-order-router",
"version": "4.0.10",
"version": "4.1.2",
"description": "Mauve Smart Order Router",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
Expand Down
4 changes: 4 additions & 0 deletions src/routers/alpha-router/alpha-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,10 @@ export type AlphaRouterConfig = {
* This parameter should always be false. It is only included for testing purposes.
*/
forceCrossProtocol: boolean;
/**
* Force the alpha router to exclude specific tokens and their associated pools from the route.
*/
excludeTokens?: string[];
/**
* The minimum percentage of the input token to use for each route in a split route.
* All routes will have a multiple of this value. For example is distribution percentage is 5,
Expand Down
33 changes: 31 additions & 2 deletions src/routers/alpha-router/functions/get-candidate-pools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,27 @@ export async function getV3CandidatePools({
blockNumber,
});

// Only consider pools where neither tokens are to be excluded.
let prunedPoolsRaw: V3SubgraphPool[] = allPoolsRaw;
const excludeTokens = routingConfig.excludeTokens;
if (excludeTokens && excludeTokens.length > 0) {
prunedPoolsRaw = [];
for (const pool of allPoolsRaw) {
const excludeToken0 = excludeTokens.find((ex) => pool.token0.id == ex);
const excludeToken1 = excludeTokens.find((ex) => pool.token1.id == ex);

if (excludeToken0 || excludeToken1) continue;

prunedPoolsRaw.push(pool);
}
}

log.info(
{ samplePools: allPoolsRaw.slice(0, 3) },
'Got all pools from V3 subgraph provider'
);

const allPools = _.map(allPoolsRaw, (pool) => {
const allPools = _.map(prunedPoolsRaw, (pool) => {
return {
...pool,
token0: {
Expand Down Expand Up @@ -569,9 +584,23 @@ export async function getV3CandidatePools({

const tokenPairs = _.compact(tokenPairsRaw);

// Only consider pairs where neither tokens are to be excluded.
let filteredTokenPairs: [Token, Token, FeeAmount][] = tokenPairs;
if (excludeTokens && excludeTokens.length > 0) {
filteredTokenPairs = [];
for (const [token0, token1, fee] of tokenPairs) {
const excludeToken0 = excludeTokens.find((ex) => token0.address == ex);
const excludeToken1 = excludeTokens.find((ex) => token1.address == ex);

if (excludeToken0 || excludeToken1) continue;

filteredTokenPairs.push([token0, token1, fee]);
}
}

const beforePoolsLoad = Date.now();

const poolAccessor = await poolProvider.getPools(tokenPairs);
const poolAccessor = await poolProvider.getPools(filteredTokenPairs);

metric.putMetric(
'V3PoolsLoad',
Expand Down
2 changes: 1 addition & 1 deletion src/routers/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import {
} from '@violetprotocol/mauve-sdk-core';
import { Route as V2RouteRaw } from '@violetprotocol/mauve-v2-sdk';
import {
MethodParameters as SDKMethodParameters,
Pool,
Position,
MethodParameters as SDKMethodParameters,
Route as V3RouteRaw,
} from '@violetprotocol/mauve-v3-sdk';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,34 @@ describe('get candidate pools', () => {
).toBeTruthy();
});

test('succeeds to get top pools while excluding WETH', async () => {
await getV3CandidatePools({
tokenIn: USDC,
tokenOut: DAI,
routeType: TradeType.EXACT_INPUT,
routingConfig: {
...ROUTING_CONFIG,
v3PoolSelection: {
...ROUTING_CONFIG.v3PoolSelection,
topNTokenInOut: 1,
},
excludeTokens: [WRAPPED_NATIVE_CURRENCY[1].address],
},
poolProvider: mockV3PoolProvider,
subgraphProvider: mockV3SubgraphProvider,
tokenProvider: mockTokenProvider,
blockedTokenListProvider: mockBlockTokenListProvider,
chainId: ChainId.MAINNET,
});

expect(
mockV3PoolProvider.getPools.calledWithExactly([
[DAI, USDC, FeeAmount.LOW],
[DAI, USDT, FeeAmount.LOW],
])
).toBeTruthy();
});

test('succeeds to get direct swap pools even if they dont exist in the subgraph', async () => {
// Mock so that DAI_WETH exists on chain, but not in the subgraph
const poolsOnSubgraph = [
Expand Down

0 comments on commit 1be9fc9

Please sign in to comment.