diff --git a/pkg/liquidity-source/algebra/v1/constant.go b/pkg/liquidity-source/algebra/v1/constant.go index 77c526ed8..0d63a9933 100644 --- a/pkg/liquidity-source/algebra/v1/constant.go +++ b/pkg/liquidity-source/algebra/v1/constant.go @@ -26,6 +26,7 @@ const ( methodGetFeeConfigOtz = "feeConfigOtz" methodGetTimepoints = "timepoints" methodGetTickSpacing = "tickSpacing" + methodGetTicks = "ticks" erc20MethodBalanceOf = "balanceOf" maxSwapLoop = 1000000 diff --git a/pkg/liquidity-source/algebra/v1/ticklens.go b/pkg/liquidity-source/algebra/v1/ticklens.go index 7edb04273..62dd46fcb 100644 --- a/pkg/liquidity-source/algebra/v1/ticklens.go +++ b/pkg/liquidity-source/algebra/v1/ticklens.go @@ -2,15 +2,14 @@ package algebrav1 import ( "context" + "math/big" "sort" "strconv" "github.com/KyberNetwork/ethrpc" "github.com/KyberNetwork/logger" mapset "github.com/deckarep/golang-set/v2" - "github.com/ethereum/go-ethereum/common" "github.com/goccy/go-json" - "github.com/samber/lo" "github.com/KyberNetwork/kyberswap-dex-lib/pkg/entity" sourcePool "github.com/KyberNetwork/kyberswap-dex-lib/pkg/source/pool" @@ -24,49 +23,43 @@ const ( ) func (d *PoolTracker) getPoolTicksFromSC(ctx context.Context, pool entity.Pool, param sourcePool.GetNewPoolStateParams) ([]TickResp, error) { - var wordIndexes []int16 - changedTicks := ticklens.GetChangedTicks(param.Logs) - if len(changedTicks) > 0 { - // only refetch changed tick if possible - wordIndexes = lo.Uniq(lo.Map(changedTicks, func(t int64, _ int) int16 { return int16(t >> 8) })) - } else { + if len(changedTicks) == 0 { // Algebra doesn't compact the tick table, so it's not feasible to fetch all for now return nil, ErrNotSupportFetchFullTick } - logger.Infof("Fetch tick from wordPosition %v to %v (%v)", wordIndexes[0], wordIndexes[len(wordIndexes)-1], changedTicks) - - chunkedWordIndexes := lo.Chunk(wordIndexes, batchSize) + logger.Infof("Fetch changed ticks (%v)", changedTicks) - var ticks []TickResp + rpcRequest := d.ethrpcClient.NewRequest() + rpcRequest.SetContext(util.NewContextWithTimestamp(ctx)) + populatedTicks := make([]Tick, len(changedTicks)) + for i, tick := range changedTicks { + rpcRequest.AddCall(ðrpc.Call{ + ABI: algebraV1PoolABI, + Target: pool.Address, + Method: methodGetTicks, + Params: []interface{}{new(big.Int).SetInt64(tick)}, + }, []interface{}{&populatedTicks[i]}) + } - for _, chunk := range chunkedWordIndexes { - rpcRequest := d.ethrpcClient.NewRequest() - rpcRequest.SetContext(util.NewContextWithTimestamp(ctx)) + resp, err := rpcRequest.TryAggregate() + if err != nil { + return nil, err + } - var populatedTicks []ticklens.PopulatedTick - rpcRequest.AddCall(ðrpc.Call{ - ABI: ticklensABI, - Target: d.config.TickLensAddress, - Method: "getPopulatedTicksInWord", - Params: []interface{}{common.HexToAddress(pool.Address), chunk}, - }, []interface{}{&populatedTicks}) - - _, err := rpcRequest.Call() - if err != nil { - return nil, err + ticks := make([]TickResp, 0, len(resp.Request.Calls)) + for i, result := range resp.Result { + if !result { + logger.Errorf("failed to try multicall with param: %v", resp.Request.Calls[i].Params) + continue } - if len(populatedTicks) > 0 { - for _, pt := range populatedTicks { - ticks = append(ticks, TickResp{ - TickIdx: pt.Tick.String(), - LiquidityGross: pt.LiquidityGross.String(), - LiquidityNet: pt.LiquidityNet.String(), - }) - } - } + ticks = append(ticks, TickResp{ + TickIdx: strconv.FormatInt(changedTicks[i], 10), + LiquidityGross: populatedTicks[i].LiquidityTotal.String(), + LiquidityNet: populatedTicks[i].LiquidityDelta.String(), + }) } // if we only fetched some ticks, then update them to the original ticks and return diff --git a/pkg/liquidity-source/algebra/v1/type.go b/pkg/liquidity-source/algebra/v1/type.go index ec3f88be9..37ad49df8 100644 --- a/pkg/liquidity-source/algebra/v1/type.go +++ b/pkg/liquidity-source/algebra/v1/type.go @@ -40,6 +40,17 @@ type TickResp struct { LiquidityNet string `json:"liquidityNet"` } +type Tick struct { + LiquidityTotal *big.Int + LiquidityDelta *big.Int + OuterFeeGrowth0Token *big.Int + OuterFeeGrowth1Token *big.Int + OuterTickCumulative *big.Int + OuterSecondsPerLiquidity *big.Int + OuterSecondsSpent uint32 + Initialized bool +} + type SubgraphPoolTicks struct { ID string `json:"id"` Ticks []TickResp `json:"ticks"`