Skip to content
This repository has been archived by the owner on Apr 25, 2024. It is now read-only.

Commit

Permalink
add token taxes to price impact calculations
Browse files Browse the repository at this point in the history
  • Loading branch information
tinaszheng committed Sep 19, 2023
1 parent 70e23a3 commit f50d52f
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 9 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"license": "MIT",
"dependencies": {
"@ethersproject/abi": "^5.5.0",
"@uniswap/sdk-core": "^4",
"@uniswap/sdk-core": "^4.0.7",
"@uniswap/swap-router-contracts": "^1.1.0",
"@uniswap/v2-sdk": "^3.2.0",
"@uniswap/v3-sdk": "^3.10.0"
Expand Down
3 changes: 3 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Percent } from '@uniswap/sdk-core'
import JSBI from 'jsbi'

export const MSG_SENDER = '0x0000000000000000000000000000000000000001'
Expand All @@ -8,3 +9,5 @@ export const ONE = JSBI.BigInt(1)

// = 1 << 23 or 100000000000000000000000
export const V2_FEE_PATH_PLACEHOLDER = 8388608

export const ZERO_PERCENT = new Percent(ZERO)
36 changes: 36 additions & 0 deletions src/entities/trade.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { sqrt, Token, CurrencyAmount, TradeType, WETH9, Ether, Percent, Price } from '@uniswap/sdk-core'
import { BigNumber } from '@ethersproject/bignumber';

import JSBI from 'jsbi'
import { MixedRoute, RouteV2, RouteV3 } from './route'
import { Trade } from './trade'
Expand All @@ -21,6 +23,8 @@ describe('Trade', () => {
const token1 = new Token(1, '0x0000000000000000000000000000000000000002', 18, 't1', 'token1')
const token2 = new Token(1, '0x0000000000000000000000000000000000000003', 18, 't2', 'token2')
const token3 = new Token(1, '0x0000000000000000000000000000000000000004', 18, 't3', 'token3')
const token4WithTax = new Token(1, '0x0000000000000000000000000000000000000005', 18, 't4', 'token4', false, BigNumber.from(100), BigNumber.from(100))
const token5WithTax = new Token(1, '0x0000000000000000000000000000000000000005', 18, 't5', 'token5', false, BigNumber.from(500), BigNumber.from(500))

function v2StylePool(
reserve0: CurrencyAmount<Token>,
Expand Down Expand Up @@ -116,6 +120,16 @@ describe('Trade', () => {
CurrencyAmount.fromRawAmount(token1, JSBI.BigInt(100000))
)

const pool_tax_output = v2StylePool(
CurrencyAmount.fromRawAmount(weth, JSBI.BigInt(100000)),
CurrencyAmount.fromRawAmount(token4WithTax, JSBI.BigInt(100000))
)

const pool_tax_input = v2StylePool(
CurrencyAmount.fromRawAmount(token5WithTax, JSBI.BigInt(100000)),
CurrencyAmount.fromRawAmount(weth, JSBI.BigInt(100000))
)

describe('#fromRoute', () => {
it('can contain only a v3 route', async () => {
const routeOriginal = new V3RouteSDK([pool_0_1], token0, token1)
Expand Down Expand Up @@ -1160,6 +1174,28 @@ describe('Trade', () => {
})
// v3 sdk price impact tests
describe('#priceImpact', () => {
describe('with FOT fees', () => {
const routev3 = new V3RouteSDK([pool_tax_output], weth, token4WithTax)
const trade = new Trade({
v2Routes: [],
v3Routes: [
{
routev3,
inputAmount: CurrencyAmount.fromRawAmount(weth, 100),
outputAmount: CurrencyAmount.fromRawAmount(token4WithTax, 69),
},
],
tradeType: TradeType.EXACT_INPUT,
})

it('is cached', () => {
expect(trade.priceImpact === trade.priceImpact).toStrictEqual(true)
})
it('is correct', () => {
expect(trade.priceImpact.toSignificant(3)).toEqual('00.0')
})
})

describe('tradeType = EXACT_INPUT', () => {
const routev3 = new V3RouteSDK([pool_0_1, pool_1_2], token0, token2)
const mixedRoute = new MixedRouteSDK([pool_0_1, pool_1_2], token0, token2)
Expand Down
31 changes: 27 additions & 4 deletions src/entities/trade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Currency, CurrencyAmount, Fraction, Percent, Price, TradeType } from '@
import { Pair, Route as V2RouteSDK, Trade as V2TradeSDK } from '@uniswap/v2-sdk'
import { Pool, Route as V3RouteSDK, Trade as V3TradeSDK } from '@uniswap/v3-sdk'
import invariant from 'tiny-invariant'
import { ONE, ZERO } from '../constants'
import { ONE, ZERO, ZERO_PERCENT } from '../constants'
import { MixedRouteSDK } from './mixedRoute/route'
import { MixedRouteTrade as MixedRouteTradeSDK } from './mixedRoute/trade'
import { IRoute, MixedRoute, RouteV2, RouteV3 } from './route'
Expand Down Expand Up @@ -159,7 +159,27 @@ export class Trade<TInput extends Currency, TOutput extends Currency, TTradeType
}

/**
* The cached result of the price impact computation
* Returns the sell tax of the input token
*/
public get inputTax(): Percent {
const inputCurrency = this.inputAmount.currency
if (inputCurrency.isNative || !inputCurrency.sellFeeBps) return ZERO_PERCENT

return new Percent(inputCurrency.sellFeeBps.toNumber(), 10000)
}

/**
* Returns the buy tax of the output token
*/
public get outputTax(): Percent {
const outputCurrency = this.outputAmount.currency
if (outputCurrency.isNative || !outputCurrency.buyFeeBps) return ZERO_PERCENT

return new Percent(outputCurrency.buyFeeBps.toNumber(), 10000)
}

/**
* The cached result of the price impact computation, excluding FOT fees
* @private
*/
private _priceImpact: Percent | undefined
Expand All @@ -174,10 +194,13 @@ export class Trade<TInput extends Currency, TOutput extends Currency, TTradeType
let spotOutputAmount = CurrencyAmount.fromRawAmount(this.outputAmount.currency, 0)
for (const { route, inputAmount } of this.swaps) {
const midPrice = route.midPrice
spotOutputAmount = spotOutputAmount.add(midPrice.quote(inputAmount))

const postTaxInputAmount = inputAmount.multiply(new Fraction(ONE).subtract(this.inputTax))
spotOutputAmount = spotOutputAmount.add(midPrice.quote(postTaxInputAmount))
}

const priceImpact = spotOutputAmount.subtract(this.outputAmount).divide(spotOutputAmount)
const preTaxOutputAmount = this.outputAmount.divide(new Fraction(ONE).subtract(this.outputTax))
const priceImpact = spotOutputAmount.subtract(preTaxOutputAmount).divide(spotOutputAmount)
this._priceImpact = new Percent(priceImpact.numerator, priceImpact.denominator)

return this._priceImpact
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1575,10 +1575,10 @@
resolved "https://registry.npmjs.org/@uniswap/lib/-/lib-4.0.1-alpha.tgz"
integrity sha512-f6UIliwBbRsgVLxIaBANF6w09tYqc6Y/qXdsrbEmXHyFA7ILiKrIwRFXe1yOg8M3cksgVsO9N7yuL2DdCGQKBA==

"@uniswap/sdk-core@^4", "@uniswap/sdk-core@^4.0.2":
version "4.0.2"
resolved "https://registry.yarnpkg.com/@uniswap/sdk-core/-/sdk-core-4.0.2.tgz#2eca2b5bf00bad74519aef918465c19218285b4b"
integrity sha512-rR5xobsAAP4yMYC7C+0+duVx0pFoDn2lV9kTWpoKgH1WJuw7hD1uDEvuevU2dL89TuixVgGvnYd0QxmrMtsIlg==
"@uniswap/sdk-core@^4", "@uniswap/sdk-core@^4.0.2", "@uniswap/sdk-core@^4.0.7":
version "4.0.7"
resolved "https://registry.yarnpkg.com/@uniswap/sdk-core/-/sdk-core-4.0.7.tgz#90dfd070d7e44494234618af398da158363ae827"
integrity sha512-jscx7KUIWzQatcL5PHY6xy0gEL9IGQcL5h/obxzX9foP2KoNk9cq66Ia8I2Kvpa7zBcPOeW1hU0hJNBq6CzcIQ==
dependencies:
"@ethersproject/address" "^5.0.2"
big.js "^5.2.2"
Expand Down

0 comments on commit f50d52f

Please sign in to comment.