github.com/0xPolygon/supernets2-node@v0.0.0-20230711153321-2fe574524eaa/pricegetter/priceprovider/uniswap/client.go (about) 1 package uniswap 2 3 import ( 4 "context" 5 "fmt" 6 "math/big" 7 8 "github.com/0xPolygon/supernets2-node/log" 9 "github.com/ethereum/go-ethereum/accounts/abi/bind" 10 "github.com/ethereum/go-ethereum/common" 11 "github.com/ethereum/go-ethereum/ethclient" 12 ) 13 14 var ( 15 x96 = new(big.Float).SetInt(big.NewInt(0).Exp(big.NewInt(2), big.NewInt(96), nil)) // nolint:gomnd 16 uniswapAddressEthMaticPool = common.HexToAddress("0x290a6a7460b308ee3f19023d2d00de604bcf5b42") 17 ) 18 19 // PriceProvider price proved which takes price from the eth/matic pool from uniswap 20 type PriceProvider struct { 21 Uni *Uniswap 22 } 23 24 // NewPriceProvider init uniswap price provider 25 func NewPriceProvider(URL string) (*PriceProvider, error) { 26 ethClient, err := ethclient.Dial(URL) 27 if err != nil { 28 log.Errorf("error connecting to %s: %+v", URL, err) 29 return nil, err 30 } 31 32 uni, err := NewUniswap(uniswapAddressEthMaticPool, ethClient) 33 if err != nil { 34 return nil, err 35 } 36 return &PriceProvider{Uni: uni}, nil 37 } 38 39 // SqrtPriceX96ToPrice convert uniswap v3 sqrt price in x96 format to big.Float 40 // calculation taken from here - https://docs.uniswap.org/sdk/guides/fetching-prices#understanding-sqrtprice 41 func sqrtPriceX96ToPrice(sqrtPriceX96 *big.Int) (price *big.Float) { 42 d := big.NewFloat(0).Quo(new(big.Float).SetInt(sqrtPriceX96), x96) 43 p := big.NewFloat(0).Mul(d, d) 44 45 price = big.NewFloat(0).Quo(big.NewFloat(1), p) 46 return 47 } 48 49 // GetEthToMaticPrice price from the uniswap pool contract 50 func (c *PriceProvider) GetEthToMaticPrice(ctx context.Context) (*big.Float, error) { 51 slot, err := c.Uni.Slot0(&bind.CallOpts{Context: ctx}) 52 if err != nil { 53 return nil, fmt.Errorf("failed to get matic price from uniswap: %v", err) 54 } 55 56 return sqrtPriceX96ToPrice(slot.SqrtPriceX96), nil 57 }