kabu_defi_pools/state_readers/
uniswapv3_quoter.rs1use alloy::primitives::aliases::U24;
2use alloy::primitives::{Address, U160, U256};
3use alloy::sol_types::SolCall;
4use alloy_evm::EvmEnv;
5use eyre::Result;
6use kabu_defi_abi::uniswap_periphery::IQuoterV2;
7use kabu_evm_db::KabuDBError;
8use kabu_evm_utils::evm_call;
9use kabu_types_entities::PoolError;
10use revm::DatabaseRef;
11
12pub struct UniswapV3QuoterV2Encoder {}
13
14impl UniswapV3QuoterV2Encoder {
15 pub fn quote_exact_output_encode(token_in: Address, token_out: Address, fee: U24, price_limit: U160, amount_out: U256) -> Vec<u8> {
16 let params = IQuoterV2::QuoteExactOutputSingleParams {
17 tokenIn: token_in,
18 tokenOut: token_out,
19 amount: amount_out,
20 fee,
21 sqrtPriceLimitX96: price_limit,
22 };
23 let call = IQuoterV2::quoteExactOutputSingleCall { params };
24 call.abi_encode()
25 }
26
27 pub fn quote_exact_input_encode(token_in: Address, token_out: Address, fee: U24, price_limit: U160, amount_in: U256) -> Vec<u8> {
28 let params = IQuoterV2::QuoteExactInputSingleParams {
29 tokenIn: token_in,
30 tokenOut: token_out,
31 amountIn: amount_in,
32 fee,
33 sqrtPriceLimitX96: price_limit,
34 };
35 let call = IQuoterV2::quoteExactInputSingleCall { params };
36 call.abi_encode()
37 }
38
39 pub fn quote_exact_input_result_decode(data: &[u8]) -> Result<U256, PoolError> {
40 let ret = IQuoterV2::quoteExactInputSingleCall::abi_decode_returns(data);
41 match ret {
42 Ok(r) => Ok(r.amountOut),
43 Err(e) => Err(PoolError::AbiDecodingError { method: "quoteExactInputSingle", source: e }),
44 }
45 }
46 pub fn quote_exact_output_result_decode(data: &[u8]) -> Result<U256, PoolError> {
47 let ret = IQuoterV2::quoteExactOutputSingleCall::abi_decode_returns(data);
48 match ret {
49 Ok(r) => Ok(r.amountIn),
50 Err(e) => Err(PoolError::AbiDecodingError { method: "quoteExactOutputSingle", source: e }),
51 }
52 }
53}
54
55pub struct UniswapV3QuoterV2StateReader {}
56
57impl UniswapV3QuoterV2StateReader {
58 pub fn quote_exact_input<DB: DatabaseRef<Error = KabuDBError> + ?Sized>(
59 db: &DB,
60 quoter_address: Address,
61 token_from: Address,
62 token_to: Address,
63 fee: U24,
64 amount: U256,
65 ) -> Result<(U256, u64), PoolError> {
66 let input = UniswapV3QuoterV2Encoder::quote_exact_input_encode(token_from, token_to, fee, U160::ZERO, amount);
67 let (value, gas_used, _) = evm_call(db, EvmEnv::default(), quoter_address, input)?;
68
69 let ret = UniswapV3QuoterV2Encoder::quote_exact_input_result_decode(&value)?;
70 Ok((ret, gas_used))
71 }
72
73 pub fn quote_exact_output<DB: DatabaseRef<Error = KabuDBError> + ?Sized>(
74 db: &DB,
75 quoter_address: Address,
76 token_from: Address,
77 token_to: Address,
78 fee: U24,
79 amount: U256,
80 ) -> Result<(U256, u64), PoolError> {
81 let input = UniswapV3QuoterV2Encoder::quote_exact_output_encode(token_from, token_to, fee, U160::ZERO, amount);
82 let (value, gas_used, _) = evm_call(db, EvmEnv::default(), quoter_address, input)?;
83
84 let ret = UniswapV3QuoterV2Encoder::quote_exact_output_result_decode(&value)?;
85 Ok((ret, gas_used))
86 }
87}