getRate on BSC for EOS returns the wrong price
Closed this issue · 1 comments
Referring to 0x0AdDd25a91563696D8567Df78D5A01C9a991F9B8
deployed on BSC.
When calling the getRate function with EOS(0x56b6fb708fc5732dec1afc8d8556423a2edccbd6
) and USDT(0x55d398326f99059fF775485246999027B3197955
) as the src and dst tokens, the rate returned is ~$360,000 while it is supposed to be ~$0.84.
Your issue is that the getRate
method uses all available pools, but there are pools with low liquidity that have a significantly incorrect price, which affects the overall price. Below is a detailed breakdown of prices across various oracles for your pair of tokens.
Oracle: UniswapV2LikeOracle_Demax
Address: 0x7bdc6954e1c7869B4147A320d589689F628E9921
Price = 3239690166096254464.00
┌─────────┬───────────┬──────────────────────────┬─────────────┐
│ (index) │ connector │ rate │ weight │
├─────────┼───────────┼──────────────────────────┼─────────────┤
│ 0 │ 'WBNB' │ '3239721194242442752.00' │ '104411335' │
│ 1 │ 'NONE' │ '2.77' │ '1000' │
└─────────┴───────────┴──────────────────────────┴─────────────┘
----------------------
Oracle: MooniswapOracle
Address: 0x5F6a6428756CfAF96584286Ef9f7411621196f3A
Price = 0.80
┌─────────┬───────────┬────────┬───────────────────────┐
│ (index) │ connector │ rate │ weight │
├─────────┼───────────┼────────┼───────────────────────┤
│ 0 │ '1INCH' │ '0.92' │ '535286847671266542' │
│ 1 │ 'NONE' │ '0.78' │ '2818727835504398871' │
└─────────┴───────────┴────────┴───────────────────────┘
----------------------
Oracle: UniswapV2LikeOracle_Pancake_1
Address: 0x1b947aF8b3dd6aa96F8726cd92c894D0Ba6367a3
Price = 0.86
┌─────────┬───────────┬────────┬────────────────────────┐
│ (index) │ connector │ rate │ weight │
├─────────┼───────────┼────────┼────────────────────────┤
│ 0 │ 'BUSD' │ '1.62' │ '198324688711213' │
│ 1 │ 'WBNB' │ '0.86' │ '35773437593157412868' │
│ 2 │ 'NONE' │ '0.75' │ '4480085988904059' │
└─────────┴───────────┴────────┴────────────────────────┘
----------------------
Oracle: UniswapV2LikeOracle_Pancake_2
Address: 0xB9fa95a38D50c5Bad1eA2b4E85e106Fe886cCb3A
Price = 0.85
┌─────────┬───────────┬────────┬─────────────────────────┐
│ (index) │ connector │ rate │ weight │
├─────────┼───────────┼────────┼─────────────────────────┤
│ 0 │ 'ETH' │ '0.86' │ '3055569201701171013' │
│ 1 │ 'WBNB' │ '0.85' │ '742021709480143285769' │
│ 2 │ 'NONE' │ '0.84' │ '109696367643052161524' │
│ 3 │ 'BUSD' │ '0.68' │ '296939730542098356' │
└─────────┴───────────┴────────┴─────────────────────────┘
----------------------
Oracle: UniswapV3LikeOracle_Pancake
Address: 0xB4039b37d09772801a51764537c167445f52F48b
Price = 0.86
┌─────────┬───────────┬────────┬────────────────────────┐
│ (index) │ connector │ rate │ weight │
├─────────┼───────────┼────────┼────────────────────────┤
│ 0 │ 'WBNB' │ '0.86' │ '20535579761137326268' │
└─────────┴───────────┴────────┴────────────────────────┘
----------------------
Oracle: UniswapV2LikeOracle_Thugswap
Address: 0x7bBc0156c31A19097eEd6B636AA2F4AB8A31BFD9
Price = 0.86
┌─────────┬───────────┬────────┬───────────────────────┐
│ (index) │ connector │ rate │ weight │
├─────────┼───────────┼────────┼───────────────────────┤
│ 0 │ 'WBNB' │ '0.86' │ '2980546721554128661' │
└─────────┴───────────┴────────┴───────────────────────┘
As it is evident, in the DEX Demax
, there's liquidity is provided through a connector token in pool whose price, despite having a very small weight in liquidity, greatly influences the overall weighted price.
Specifically, the pool's reserves are as follows:
_reserve0: 1
_reserve1: 10901727047529735
This significant imbalance in reserves is impact the price calculations within the EOS -> WBNB
pool, and within the EOS -> WBNB -> USDT
rate.
To avoid the impact of such pools on the weighted price, use the getRateWithThreshold
method. The thresholdFilter
parameter in it is a value from 0 to 99 percent, used to filter out pools where the weight is less than this percentage of the largest weight among all found pools.
getRate
is essentially getRateWithThreshold
with thresholdFilter=0
. It is retained in the contract for compatibility with utilities that worked with previous versions of the oracle. I recommend using methods where you can set the thresholdFilter
based on your needs, for example, 10 percent.