Skip to content

Commit

Permalink
Feature: V2 routes quote with fee-on-transfer fees off the quote amou…
Browse files Browse the repository at this point in the history
…nt (#395)

* sor quote with fot fees

* prettier

* remove comments in quote provider and alpha router pass in enable FOT flag

* remove comments in quote provider and alpha router pass in enable FOT flag

* address feedback

* flatten instead of flatMap

* fix integ-test after making tokenPropertiesProvider a required property in alpha router

* fix token properties provider unit test

* update sdk-core to use Token with fot tax fields

* fix CLI command to include FOT fee fetching

* fix cli for passing in enableFOT flag

* pass enable FOT flag to v2 subgraph candidate pools loading

* make tokenValidatorProvider before tokenPropertiesProvider due to dependencies

* fix v2 quote provider to get the fot tax from the pool objects from subgraph

* populate enable fot tax everywhere to v2 pool provider

* fix quote provider copy paste error

* get rid of explicit enableFeeOnTransferFeeFetching passing

* Revert "fix quote provider copy paste error"

This reverts commit 5587a4e.

* actual quote provider copy paste error fix

* replace tokenIn and tokenOut with fox tax one after getting the candidate pools

* amount distribution also adding fot tax

* remove quote provider changes

* v2 get routes from chain and cache use pools to re instantiate tokens with fox tax

* get amount distribution add back black line

* cached routes get pools for matched tokenIn and tokenOut only once

* compute all v2 routes no longer need to get token with fot tax again

* fix quote cli exact out to pass in debugRouting and enableFeeOnTransferFeeFetching as well

* fix the input currency amount to not mutate during the swap methods

* use currency for getSwapRouteFromCache v2 amountWithFotTax

* amount to flash borror 10x for rebase tokens e.g. stETH

* bump v2-sdk version

* extract matched pools to for tokens to util functions

* @mikeki offline feedback on no need to filter pools on getSwapRouteFromCache, because writing into Cached Routes can have FOT Token instances

* 3.16.22

* fix cached routes side of bugs that caused fot quote to not work properly

* remove custom pool reserve matching token logics
  • Loading branch information
jsy1218 authored Sep 12, 2023
1 parent 59ce2bc commit 725907d
Show file tree
Hide file tree
Showing 16 changed files with 315 additions and 124 deletions.
20 changes: 19 additions & 1 deletion cli/base-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,17 @@ import {
setGlobalMetric,
SimulationStatus,
TenderlySimulator,
TokenPropertiesProvider,
TokenProvider,
TokenValidatorProvider,
UniswapMulticallProvider,
V2PoolProvider,
V3PoolProvider,
V3RouteWithValidQuote,
} from '../src';
import { LegacyGasPriceProvider } from '../src/providers/legacy-gas-price-provider';
import { OnChainGasPriceProvider } from '../src/providers/on-chain-gas-price-provider';
import { OnChainTokenFeeFetcher } from '../src/providers/token-fee-fetcher';

export abstract class BaseCommand extends Command {
static flags = {
Expand Down Expand Up @@ -284,7 +287,22 @@ export abstract class BaseCommand extends Command {
new V3PoolProvider(chainId, multicall2Provider),
new NodeJSCache(new NodeCache({ stdTTL: 360, useClones: false }))
);
const v2PoolProvider = new V2PoolProvider(chainId, multicall2Provider);
const tokenValidatorProvider = new TokenValidatorProvider(
chainId,
multicall2Provider,
new NodeJSCache(new NodeCache({ stdTTL: 360, useClones: false }))
)
const tokenFeeFetcher = new OnChainTokenFeeFetcher(
chainId,
provider
)
const tokenPropertiesProvider = new TokenPropertiesProvider(
chainId,
tokenValidatorProvider,
new NodeJSCache(new NodeCache({ stdTTL: 360, useClones: false })),
tokenFeeFetcher
)
const v2PoolProvider = new V2PoolProvider(chainId, multicall2Provider, tokenPropertiesProvider);

const tenderlySimulator = new TenderlySimulator(
chainId,
Expand Down
8 changes: 8 additions & 0 deletions cli/commands/quote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export class Quote extends BaseCommand {
default: false,
}),
simulate: flags.boolean({ required: false, default: false }),
debugRouting: flags.boolean({ required: false, default: true }),
enableFeeOnTransferFeeFetching: flags.boolean({ required: false, default: true }),
};

async run() {
Expand Down Expand Up @@ -63,6 +65,8 @@ export class Quote extends BaseCommand {
forceCrossProtocol,
forceMixedRoutes,
simulate,
debugRouting,
enableFeeOnTransferFeeFetching
} = flags;

const topNSecondHopForTokenAddress = new MapWithLowerCaseKey();
Expand Down Expand Up @@ -151,6 +155,8 @@ export class Quote extends BaseCommand {
protocols,
forceCrossProtocol,
forceMixedRoutes,
debugRouting,
enableFeeOnTransferFeeFetching,
}
);
} else {
Expand Down Expand Up @@ -186,6 +192,8 @@ export class Quote extends BaseCommand {
protocols,
forceCrossProtocol,
forceMixedRoutes,
debugRouting,
enableFeeOnTransferFeeFetching,
}
);
}
Expand Down
44 changes: 22 additions & 22 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@uniswap/smart-order-router",
"version": "3.16.21",
"version": "3.16.22",
"description": "Uniswap Smart Order Router",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
Expand Down Expand Up @@ -38,9 +38,9 @@
"@uniswap/token-lists": "^1.0.0-beta.31",
"@uniswap/universal-router": "^1.0.1",
"@uniswap/universal-router-sdk": "^1.5.7",
"@uniswap/v2-sdk": "^3.2.0",
"@uniswap/v2-sdk": "^3.2.1",
"@uniswap/v3-sdk": "^3.10.0",
"@uniswap/sdk-core": "^4.0.6",
"@uniswap/sdk-core": "^4.0.7",
"async-retry": "^1.3.1",
"await-timeout": "^1.1.1",
"axios": "^0.21.1",
Expand Down
4 changes: 4 additions & 0 deletions src/providers/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ export type ProviderConfig = {
* Debug flag to test some codepaths
*/
debugRouting?: boolean;
/**
* Flag for token properties provider to enable fetching fee-on-transfer tokens.
*/
enableFeeOnTransferFeeFetching?: boolean;
};

export type LocalCacheEntry<T> = {
Expand Down
5 changes: 3 additions & 2 deletions src/providers/token-fee-fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ const FEE_DETECTOR_ADDRESS = (chainId: ChainId) => {

// Amount has to be big enough to avoid rounding errors, but small enough that
// most v2 pools will have at least this many token units
// 10000 is the smallest number that avoids rounding errors in bps terms
const AMOUNT_TO_FLASH_BORROW = '10000';
// 100000 is the smallest number that avoids rounding errors in bps terms
// 10000 was not sufficient due to rounding errors for rebase token (e.g. stETH)
const AMOUNT_TO_FLASH_BORROW = '100000';
// 1M gas limit per validate call, should cover most swap cases
const GAS_LIMIT_PER_VALIDATE = 1_000_000;

Expand Down
9 changes: 7 additions & 2 deletions src/providers/token-properties-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,19 @@ export class TokenPropertiesProvider implements ITokenPropertiesProvider {
private tokenValidatorProvider: ITokenValidatorProvider,
private tokenPropertiesCache: ICache<TokenPropertiesResult>,
private tokenFeeFetcher: ITokenFeeFetcher,
private allowList = DEFAULT_ALLOWLIST
private allowList = DEFAULT_ALLOWLIST,
) {}

public async getTokensProperties(
tokens: Token[],
providerConfig?: ProviderConfig
): Promise<TokenPropertiesMap> {
const tokenToResult: TokenPropertiesMap = {};

if (!providerConfig?.enableFeeOnTransferFeeFetching || this.chainId !== ChainId.MAINNET) {
return tokenToResult;
}

const nonAllowlistTokens = tokens.filter(
(token) => !this.allowList.has(token.address.toLowerCase())
);
Expand All @@ -57,7 +63,6 @@ export class TokenPropertiesProvider implements ITokenPropertiesProvider {
nonAllowlistTokens,
providerConfig
);
const tokenToResult: TokenPropertiesMap = {};

tokens.forEach((token) => {
if (this.allowList.has(token.address.toLowerCase())) {
Expand Down
Loading

0 comments on commit 725907d

Please sign in to comment.