forked from Uniswap/v3-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathquoter.ts
79 lines (74 loc) · 2.84 KB
/
quoter.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import { Interface } from '@ethersproject/abi'
import { BigintIsh, Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core'
import { encodeRouteToPath } from './utils'
import { MethodParameters, toHex } from './utils/calldata'
import { abi } from '@uniswap/v3-periphery/artifacts/contracts/lens/Quoter.sol/Quoter.json'
import { Route } from './entities'
import invariant from 'tiny-invariant'
/**
* Optional arguments to send to the quoter.
*/
export interface QuoteOptions {
/**
* The optional price limit for the trade.
*/
sqrtPriceLimitX96?: BigintIsh
}
/**
* Represents the Uniswap V3 QuoterV1 contract with a method for returning the formatted
* calldata needed to call the quoter contract.
*/
export abstract class SwapQuoter {
public static INTERFACE: Interface = new Interface(abi)
/**
* Produces the on-chain method name of the appropriate function within QuoterV2,
* and the relevant hex encoded parameters.
* @template TInput The input token, either Ether or an ERC-20
* @template TOutput The output token, either Ether or an ERC-20
* @param route The swap route, a list of pools through which a swap can occur
* @param amount The amount of the quote, either an amount in, or an amount out
* @param tradeType The trade type, either exact input or exact output
* @returns The formatted calldata
*/
public static quoteCallParameters<TInput extends Currency, TOutput extends Currency>(
route: Route<TInput, TOutput>,
amount: CurrencyAmount<TInput | TOutput>,
tradeType: TradeType,
options: QuoteOptions = {}
): MethodParameters {
const singleHop = route.pools.length === 1
const quoteAmount: string = toHex(amount.quotient)
let calldata: string
if (singleHop) {
if (tradeType === TradeType.EXACT_INPUT) {
calldata = SwapQuoter.INTERFACE.encodeFunctionData(`quoteExactInputSingle`, [
route.tokenPath[0].address,
route.tokenPath[1].address,
route.pools[0].fee,
quoteAmount,
toHex(options?.sqrtPriceLimitX96 ?? 0)
])
} else {
calldata = SwapQuoter.INTERFACE.encodeFunctionData(`quoteExactOutputSingle`, [
route.tokenPath[0].address,
route.tokenPath[1].address,
route.pools[0].fee,
quoteAmount,
toHex(options?.sqrtPriceLimitX96 ?? 0)
])
}
} else {
invariant(options?.sqrtPriceLimitX96 === undefined, 'MULTIHOP_PRICE_LIMIT')
const path: string = encodeRouteToPath(route, tradeType === TradeType.EXACT_OUTPUT)
if (tradeType === TradeType.EXACT_INPUT) {
calldata = SwapQuoter.INTERFACE.encodeFunctionData('quoteExactInput', [path, quoteAmount])
} else {
calldata = SwapQuoter.INTERFACE.encodeFunctionData('quoteExactOutput', [path, quoteAmount])
}
}
return {
calldata,
value: toHex(0)
}
}
}