Skip to content

Commit

Permalink
feat: Add PancakeSwap exchange for SWBT/WBTC support (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
rbajollari authored Aug 14, 2024
1 parent b9a0dea commit 9a0694d
Show file tree
Hide file tree
Showing 6 changed files with 2,754 additions and 4 deletions.
2,643 changes: 2,643 additions & 0 deletions abi/pancake/pancake_pool.go

Large diffs are not rendered by default.

31 changes: 28 additions & 3 deletions client/spot_prices.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/ethereum/go-ethereum/common"
balancerpool "github.com/ojo-network/ethereum-api/abi/balancer/pool"
"github.com/ojo-network/ethereum-api/abi/camelot"
"github.com/ojo-network/ethereum-api/abi/pancake"
"github.com/ojo-network/ethereum-api/abi/uniswap"
"github.com/ojo-network/ethereum-api/pool"
"github.com/ojo-network/indexer/indexer"
Expand All @@ -27,15 +28,19 @@ func (c *Client) PollSpotPrices(pools []pool.Pool) {
switch c.poolContract {
case pool.PoolUniswap:
spotPrice = c.QueryUniswapSpotPrice(p, blockNum)
c.logger.Info().Interface("spotPrice", spotPrice).Msg("spot price received")
c.logger.Info().Interface("Uniswap spotPrice", spotPrice).Msg("spot price received")
c.indexer.AddPrice(spotPrice)
case pool.PoolAlgebra:
spotPrice = c.QueryAlgebraSpotPrice(p, blockNum)
c.logger.Info().Interface("spotPrice", spotPrice).Msg("spot price received")
c.logger.Info().Interface("Alegbra spotPrice", spotPrice).Msg("spot price received")
c.indexer.AddPrice(spotPrice)
case pool.PoolBalancer:
spotPrice = c.QueryBalancerSpotPrice(p, blockNum)
c.logger.Info().Interface("spotPrice", spotPrice).Msg("spot price received")
c.logger.Info().Interface("Balancer spotPrice", spotPrice).Msg("spot price received")
c.indexer.AddPrice(spotPrice)
case pool.PoolPancake:
spotPrice = c.QueryPancakeSpotPrice(p, blockNum)
c.logger.Info().Interface("Pancake spotPrice", spotPrice).Msg("spot price received")
c.indexer.AddPrice(spotPrice)
}
}
Expand Down Expand Up @@ -104,3 +109,23 @@ func (c *Client) QueryBalancerSpotPrice(p pool.Pool, blockNum uint64) indexer.Sp
Price: sdkmath.LegacyNewDecFromBigIntWithPrec(poolRate, 18),
}
}

// QueryPancakeSpotPrice queries the spot price of a pancake pool
func (c *Client) QueryPancakeSpotPrice(p pool.Pool, blockNum uint64) indexer.SpotPrice {
pancakeCaller, err := pancake.NewPancakeCaller(common.HexToAddress(p.Address), c.ethClient)
if err != nil {
c.reportError(fmt.Errorf("error initializing %s pool caller: %w", p.ExchangePair(), err))
return indexer.SpotPrice{}
}
slot0, err := pancakeCaller.Slot0(nil)
if err != nil {
c.reportError(fmt.Errorf("error getting %s pool balance: %w", p.ExchangePair(), err))
return indexer.SpotPrice{}
}
return indexer.SpotPrice{
BlockNum: indexer.BlockNum(blockNum),
Timestamp: utils.CurrentUnixTime(),
ExchangePair: p.ExchangePair(),
Price: p.SqrtPriceX96ToDec(slot0.SqrtPriceX96),
}
}
41 changes: 40 additions & 1 deletion client/swaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
balancerpool "github.com/ojo-network/ethereum-api/abi/balancer/pool"
"github.com/ojo-network/ethereum-api/abi/balancer/vault"
"github.com/ojo-network/ethereum-api/abi/camelot"
"github.com/ojo-network/ethereum-api/abi/pancake"
"github.com/ojo-network/ethereum-api/abi/uniswap"
"github.com/ojo-network/ethereum-api/pool"
)
Expand Down Expand Up @@ -36,6 +37,11 @@ func (c *Client) WatchSwapsAndRestart(p pool.Pool) {
if err != nil {
c.reportError(fmt.Errorf("error watching %s swap events", p.ExchangePair()))
}
case pool.PoolPancake:
err := c.WatchPancakeSwapEvent(p)
if err != nil {
c.reportError(fmt.Errorf("error watching %s swap events", p.ExchangePair()))
}
}
}
}
Expand Down Expand Up @@ -131,7 +137,7 @@ func (c *Client) WatchBalancerSwapEvent(p pool.Pool) error {
tokenInParam := make([]common.Address, 1)
tokenInParam[0] = common.HexToAddress(p.BaseAddress)
tokenOutParam := []common.Address{}
for _, tokenAddress := range p.QuoteAddresses{
for _, tokenAddress := range p.QuoteAddresses {
tokenOutParam = append(tokenOutParam, common.HexToAddress(tokenAddress))
}

Expand Down Expand Up @@ -171,3 +177,36 @@ func (c *Client) WatchBalancerSwapEvent(p pool.Pool) error {
}
}
}

// WatchPancakeSwapEvent watches for swap events on a pancake pool
func (c *Client) WatchPancakeSwapEvent(p pool.Pool) error {
pancakeFilterer, err := pancake.NewPancakeFilterer(common.HexToAddress(p.Address), c.ethClient)
if err != nil {
return err
}

eventSink := make(chan *pancake.PancakeSwap)
opts := &bind.WatchOpts{Start: nil, Context: c.ctx}
c.logger.Info().Msgf("subscribing to %s swap events", p.ExchangePair())
subscription, err := pancakeFilterer.WatchSwap(opts, eventSink, nil, nil)
if err != nil {
return err
}

for {
select {
case <-c.ctx.Done():
c.logger.Info().Msgf("unsubscribing from %s swap events", p.ExchangePair())
subscription.Unsubscribe()
return nil
case err := <-subscription.Err():
return err
case event := <-eventSink:
swap := p.ConvertPancakeEventToSwap(event)
spotPrice := p.ConvertPancakeEventToSpotPrice(event)
c.logger.Info().Interface("pancake swap", swap).Msg("pancake swap event received")
c.indexer.AddSwap(swap)
c.indexer.AddPrice(spotPrice)
}
}
}
30 changes: 30 additions & 0 deletions pool/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/ojo-network/ethereum-api/abi/balancer/vault"
"github.com/ojo-network/ethereum-api/abi/camelot"
"github.com/ojo-network/ethereum-api/abi/pancake"
"github.com/ojo-network/ethereum-api/abi/uniswap"
"github.com/ojo-network/indexer/indexer"
"github.com/ojo-network/indexer/utils"
Expand Down Expand Up @@ -84,6 +85,25 @@ func (p *Pool) ConvertBalancerEventToSwap(event *vault.PoolSwap, price *big.Int)
}
}

func (p *Pool) ConvertPancakeEventToSpotPrice(event *pancake.PancakeSwap) indexer.SpotPrice {
return indexer.SpotPrice{
BlockNum: indexer.BlockNum(event.Raw.BlockNumber),
Timestamp: utils.CurrentUnixTime(),
ExchangePair: p.ExchangePair(),
Price: p.SqrtPriceX96ToDec(event.SqrtPriceX96),
}
}

func (p *Pool) ConvertPancakeEventToSwap(event *pancake.PancakeSwap) indexer.Swap {
return indexer.Swap{
BlockNum: indexer.BlockNum(event.Raw.BlockNumber),
Timestamp: utils.CurrentUnixTime(),
ExchangePair: p.ExchangePair(),
Price: p.SqrtPriceX96ToDec(event.SqrtPriceX96),
Volume: p.swapPancakeVolume(event),
}
}

func (p *Pool) SqrtPriceX96ToDec(sqrtPriceX96 *big.Int) sdkmath.LegacyDec {
sdkValue := sdkmath.LegacyNewDecFromBigInt(sqrtPriceX96)

Expand Down Expand Up @@ -138,3 +158,13 @@ func (p *Pool) swapBalancerVolume(event *vault.PoolSwap) sdkmath.LegacyDec {
return volume.Quo(sdkmath.LegacyNewDec(10).Power(uint64(p.BaseDecimal)))
}
}

func (p *Pool) swapPancakeVolume(event *pancake.PancakeSwap) sdkmath.LegacyDec {
if p.InvertPrice {
volume := sdkmath.LegacyNewDecFromBigInt(event.Amount1).Abs()
return volume.Quo(sdkmath.LegacyNewDec(10).Power(uint64(p.QuoteDecimal)))
} else {
volume := sdkmath.LegacyNewDecFromBigInt(event.Amount0).Abs()
return volume.Quo(sdkmath.LegacyNewDec(10).Power(uint64(p.BaseDecimal)))
}
}
3 changes: 3 additions & 0 deletions pool/supported_exchanges.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ type PoolContract string
const ExchangeUniswap ExchangeName = "uniswap"
const ExchangeCamelot ExchangeName = "camelot"
const ExchangeBalancer ExchangeName = "balancer"
const ExchangePancake ExchangeName = "pancake"
const PoolUniswap PoolContract = "uniswappool"
const PoolAlgebra PoolContract = "algebrapool"
const PoolBalancer PoolContract = "balancerpool"
const PoolPancake PoolContract = "pancakepool"

// maps exchange to pool contract of that exchange
var SupportedExchanges = map[ExchangeName]PoolContract{
ExchangeUniswap: PoolUniswap,
ExchangeCamelot: PoolAlgebra,
ExchangeBalancer: PoolBalancer,
ExchangePancake: PoolPancake,
}
10 changes: 10 additions & 0 deletions sample-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ exchanges:
base_decimal: 18
quote_decimal: 18
invert_price: false
- name: "pancake"
node_urls:
- "wss://mainnet.infura.io/ws/v3/6849a09aeeb044b592d46bcdce07ccef"
pools:
- address: "0x365EA9E5Cec960390f35b6509548e84073168A8B"
base: "SWBTC"
quote: "WBTC"
base_decimal: 18
quote_decimal: 18
invert_price: false

server:
listen_addr: "0.0.0.0:5005"
Expand Down

0 comments on commit 9a0694d

Please sign in to comment.