diff --git a/package.json b/package.json index e17008e..cf5a148 100644 --- a/package.json +++ b/package.json @@ -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" diff --git a/src/constants.ts b/src/constants.ts index 33f277d..fd46151 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,3 +1,4 @@ +import { Percent } from '@uniswap/sdk-core' import JSBI from 'jsbi' export const MSG_SENDER = '0x0000000000000000000000000000000000000001' @@ -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) diff --git a/src/entities/trade.test.ts b/src/entities/trade.test.ts index 2d9a550..fdfa0b5 100644 --- a/src/entities/trade.test.ts +++ b/src/entities/trade.test.ts @@ -1,4 +1,5 @@ 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' @@ -21,6 +22,26 @@ 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, @@ -101,6 +122,16 @@ describe('Trade', () => { CurrencyAmount.fromRawAmount(token2, JSBI.BigInt(10000)) ) + const pair_tax_output = new Pair( + CurrencyAmount.fromRawAmount(weth, JSBI.BigInt(100000)), + CurrencyAmount.fromRawAmount(token4WithTax, JSBI.BigInt(100000)) + ) + + const pair_tax_input = new Pair( + CurrencyAmount.fromRawAmount(token5WithTax, JSBI.BigInt(100000)), + CurrencyAmount.fromRawAmount(weth, JSBI.BigInt(100000)) + ) + const pool_weth_0 = v2StylePool( CurrencyAmount.fromRawAmount(weth, JSBI.BigInt(100000)), CurrencyAmount.fromRawAmount(token0, JSBI.BigInt(100000)) @@ -1160,6 +1191,50 @@ describe('Trade', () => { }) // v3 sdk price impact tests describe('#priceImpact', () => { + describe('with FOT sell fees', () => { + const routev2 = new V2RouteSDK([pair_tax_output], weth, token4WithTax) + const trade = new Trade({ + v2Routes: [ + { + routev2, + inputAmount: CurrencyAmount.fromRawAmount(weth, 100), + outputAmount: CurrencyAmount.fromRawAmount(token4WithTax, 69), + }, + ], + v3Routes: [], + tradeType: TradeType.EXACT_INPUT, + }) + + it('is cached', () => { + expect(trade.priceImpact === trade.priceImpact).toStrictEqual(true) + }) + it('is correct', () => { + expect(trade.priceImpact.toSignificant(3)).toEqual('30.3') + }) + }) + + describe('with FOT buy fees', () => { + const routev2 = new V2RouteSDK([pair_tax_input], token5WithTax, weth) + const trade = new Trade({ + v2Routes: [ + { + routev2, + inputAmount: CurrencyAmount.fromRawAmount(token5WithTax, 100), + outputAmount: CurrencyAmount.fromRawAmount(weth, 69), + }, + ], + v3Routes: [], + tradeType: TradeType.EXACT_INPUT, + }) + + it('is cached', () => { + expect(trade.priceImpact === trade.priceImpact).toStrictEqual(true) + }) + it('is correct', () => { + expect(trade.priceImpact.toSignificant(3)).toEqual('27.4') + }) + }) + 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) diff --git a/src/entities/trade.ts b/src/entities/trade.ts index 730f630..8cdce10 100644 --- a/src/entities/trade.ts +++ b/src/entities/trade.ts @@ -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' @@ -158,13 +158,35 @@ export class Trade