diff --git a/CHANGELOG.md b/CHANGELOG.md index 08acd78a1cb..947b8b7a682 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [#6788](https://github.com/osmosis-labs/osmosis/pull/6788) Improve error message when CL LP fails due to slippage bound hit. +### API Breaks + +* [#6805](https://github.com/osmosis-labs/osmosis/pull/6805) return bucket index of the current tick from LiquidityPerTickRange query + ## v20.0.0 ### Features diff --git a/proto/osmosis/concentrated-liquidity/query.proto b/proto/osmosis/concentrated-liquidity/query.proto index 5b28041dfa0..98cdb37a438 100644 --- a/proto/osmosis/concentrated-liquidity/query.proto +++ b/proto/osmosis/concentrated-liquidity/query.proto @@ -227,6 +227,8 @@ message LiquidityPerTickRangeRequest { message LiquidityPerTickRangeResponse { repeated LiquidityDepthWithRange liquidity = 1 [ (gogoproto.nullable) = false ]; + + int64 bucket_index = 2 [ (gogoproto.moretags) = "yaml:\"bucket_index\"" ]; } // ===================== QueryClaimableSpreadRewards diff --git a/x/concentrated-liquidity/bench_test.go b/x/concentrated-liquidity/bench_test.go index f59f6da612b..2070171670b 100644 --- a/x/concentrated-liquidity/bench_test.go +++ b/x/concentrated-liquidity/bench_test.go @@ -273,7 +273,7 @@ func BenchmarkGetTickLiquidityForFullRange(b *testing.B) { b.StartTimer() // System under test - liquidityNet, err := clKeeper.GetTickLiquidityForFullRange(s.Ctx, pool.GetId()) + liquidityNet, _, err := clKeeper.GetTickLiquidityForFullRange(s.Ctx, pool.GetId()) b.StopTimer() noError(b, err) diff --git a/x/concentrated-liquidity/client/cli/query.go b/x/concentrated-liquidity/client/cli/query.go index f7057e4ce89..d9b507c1422 100644 --- a/x/concentrated-liquidity/client/cli/query.go +++ b/x/concentrated-liquidity/client/cli/query.go @@ -22,6 +22,7 @@ func GetQueryCmd() *cobra.Command { osmocli.AddQueryCmd(cmd, queryproto.NewQueryClient, GetTickLiquidityNetInDirection) osmocli.AddQueryCmd(cmd, queryproto.NewQueryClient, GetPoolAccumulatorRewards) osmocli.AddQueryCmd(cmd, queryproto.NewQueryClient, GetTickAccumulatorTrackers) + osmocli.AddQueryCmd(cmd, queryproto.NewQueryClient, GetLiquidityPerTickRange) cmd.AddCommand( osmocli.GetParams[*queryproto.ParamsRequest]( types.ModuleName, queryproto.NewQueryClient), @@ -117,6 +118,17 @@ TODO: What does any of that mean...?`, }, &queryproto.LiquidityNetInDirectionRequest{} } +func GetLiquidityPerTickRange() (*osmocli.QueryDescriptor, *queryproto.LiquidityPerTickRangeRequest) { + return &osmocli.QueryDescriptor{ + Use: "liquidity-per-tick-range", + Short: "Query liquidity per tick range", + Long: `{{.Short}}{{.ExampleHeader}} +{{.CommandPrefix}} 1 + +[poolid]`, + }, &queryproto.LiquidityPerTickRangeRequest{} +} + func GetPoolAccumulatorRewards() (*osmocli.QueryDescriptor, *queryproto.PoolAccumulatorRewardsRequest) { return &osmocli.QueryDescriptor{ Use: "pool-accumulator-rewards", diff --git a/x/concentrated-liquidity/client/query_proto_wrap.go b/x/concentrated-liquidity/client/query_proto_wrap.go index f39eee27d2e..e572f023144 100644 --- a/x/concentrated-liquidity/client/query_proto_wrap.go +++ b/x/concentrated-liquidity/client/query_proto_wrap.go @@ -113,7 +113,7 @@ func (q Querier) Params(ctx sdk.Context, req clquery.ParamsRequest) (*clquery.Pa // LiquidityPerTickRange returns the amount of liquidity per every tick range // existing within the given pool. The amounts are returned as a slice of ranges with their liquidity depths. func (q Querier) LiquidityPerTickRange(ctx sdk.Context, req clquery.LiquidityPerTickRangeRequest) (*clquery.LiquidityPerTickRangeResponse, error) { - liquidity, err := q.Keeper.GetTickLiquidityForFullRange( + liquidity, bucketIndex, err := q.Keeper.GetTickLiquidityForFullRange( ctx, req.PoolId, ) @@ -121,7 +121,7 @@ func (q Querier) LiquidityPerTickRange(ctx sdk.Context, req clquery.LiquidityPer return nil, err } - return &clquery.LiquidityPerTickRangeResponse{Liquidity: liquidity}, nil + return &clquery.LiquidityPerTickRangeResponse{Liquidity: liquidity, BucketIndex: bucketIndex}, nil } // LiquidityNetInDirection returns an array of LiquidityDepthWithRange, which contains the range(lower tick and upper tick), the liquidity amount in the range, and current sqrt price. diff --git a/x/concentrated-liquidity/client/queryproto/query.pb.go b/x/concentrated-liquidity/client/queryproto/query.pb.go index 02ae0af1692..eec9d498e0f 100644 --- a/x/concentrated-liquidity/client/queryproto/query.pb.go +++ b/x/concentrated-liquidity/client/queryproto/query.pb.go @@ -704,7 +704,8 @@ func (m *LiquidityPerTickRangeRequest) GetPoolId() uint64 { } type LiquidityPerTickRangeResponse struct { - Liquidity []LiquidityDepthWithRange `protobuf:"bytes,1,rep,name=liquidity,proto3" json:"liquidity"` + Liquidity []LiquidityDepthWithRange `protobuf:"bytes,1,rep,name=liquidity,proto3" json:"liquidity"` + BucketIndex int64 `protobuf:"varint,2,opt,name=bucket_index,json=bucketIndex,proto3" json:"bucket_index,omitempty" yaml:"bucket_index"` } func (m *LiquidityPerTickRangeResponse) Reset() { *m = LiquidityPerTickRangeResponse{} } @@ -747,6 +748,13 @@ func (m *LiquidityPerTickRangeResponse) GetLiquidity() []LiquidityDepthWithRange return nil } +func (m *LiquidityPerTickRangeResponse) GetBucketIndex() int64 { + if m != nil { + return m.BucketIndex + } + return 0 +} + // ===================== QueryClaimableSpreadRewards type ClaimableSpreadRewardsRequest struct { PositionId uint64 `protobuf:"varint,1,opt,name=position_id,json=positionId,proto3" json:"position_id,omitempty" yaml:"position_id"` @@ -1662,152 +1670,154 @@ func init() { } var fileDescriptor_5c83e18b11fd607d = []byte{ - // 2315 bytes of a gzipped FileDescriptorProto + // 2339 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5a, 0x4d, 0x6c, 0x1b, 0xc7, - 0x15, 0xf6, 0xca, 0x3f, 0x31, 0x9f, 0xe5, 0xbf, 0x91, 0x2c, 0xc9, 0xb4, 0x4d, 0x3a, 0xd3, 0xba, - 0x11, 0x62, 0x8b, 0x4c, 0xfc, 0x53, 0xd7, 0x7f, 0x71, 0x44, 0x29, 0x32, 0x88, 0xc8, 0x8a, 0xbc, - 0xb6, 0xda, 0xa2, 0x87, 0x6e, 0x96, 0xbb, 0x23, 0x6a, 0xc0, 0xe5, 0x0e, 0xb5, 0x3b, 0x6b, 0x59, - 0x4d, 0x0d, 0x04, 0xc9, 0xb1, 0x40, 0x9b, 0xa2, 0xd7, 0xa2, 0x40, 0xd1, 0x4b, 0x11, 0xf4, 0xd8, - 0x4b, 0x7b, 0x6b, 0x0f, 0x85, 0xd1, 0x43, 0x10, 0xa0, 0x28, 0x50, 0xe4, 0xc0, 0xb4, 0x76, 0x0f, + 0x15, 0xf6, 0xc8, 0xbf, 0x7c, 0x96, 0xff, 0x46, 0xb2, 0x24, 0xd3, 0x36, 0xe9, 0x4c, 0xeb, 0x46, + 0x88, 0x2d, 0x32, 0xf1, 0x4f, 0x5d, 0xff, 0xc5, 0x11, 0xa5, 0xc8, 0x20, 0x22, 0x2b, 0xf2, 0xda, + 0x6a, 0x8b, 0x1e, 0xba, 0x59, 0xee, 0x8e, 0xa8, 0x05, 0x97, 0x3b, 0xd4, 0xee, 0xac, 0x6d, 0x35, + 0x35, 0x10, 0x24, 0xc7, 0x02, 0x6d, 0x8a, 0x5e, 0x8b, 0x02, 0x45, 0x2f, 0x45, 0xd0, 0x63, 0x2f, + 0xed, 0xa5, 0x68, 0x0f, 0x85, 0xd1, 0x43, 0x10, 0xa0, 0x28, 0x50, 0xe4, 0xc0, 0xb4, 0x76, 0x0f, 0x05, 0xd2, 0x16, 0xa8, 0x7a, 0xe9, 0xb1, 0xd8, 0xd9, 0xd9, 0x1f, 0x52, 0x4b, 0x71, 0x49, 0xa9, - 0xa7, 0x9e, 0xc8, 0xd9, 0xf7, 0xfb, 0xbd, 0x37, 0xf3, 0x76, 0xde, 0x23, 0xe1, 0x55, 0xe6, 0x36, - 0x99, 0x4b, 0xdd, 0xb2, 0xc1, 0x6c, 0x83, 0xd8, 0xdc, 0xd1, 0x39, 0x31, 0x67, 0x2c, 0xba, 0xee, - 0x51, 0x93, 0xf2, 0xcd, 0xf2, 0xba, 0x47, 0x9c, 0xcd, 0x52, 0xcb, 0x61, 0x9c, 0xa1, 0x0b, 0x92, - 0xb7, 0x94, 0xe4, 0x8d, 0x58, 0x4b, 0x8f, 0x5f, 0xaf, 0x11, 0xae, 0xbf, 0x9e, 0x1f, 0xaf, 0xb3, - 0x3a, 0x13, 0x12, 0x65, 0xff, 0x5b, 0x20, 0x9c, 0xbf, 0xd8, 0xc7, 0x50, 0x4b, 0x77, 0xf4, 0xa6, - 0x2b, 0x99, 0x67, 0xfa, 0x30, 0x73, 0x6a, 0x34, 0xaa, 0xf6, 0x6a, 0xa8, 0xbb, 0x60, 0x08, 0xfe, - 0x72, 0x4d, 0x77, 0x49, 0x59, 0xba, 0x51, 0x36, 0x18, 0xb5, 0x25, 0xfd, 0xd5, 0x24, 0x5d, 0x20, - 0x8a, 0xb8, 0x5a, 0x7a, 0x9d, 0xda, 0x3a, 0xa7, 0x2c, 0xe4, 0x3d, 0x5b, 0x67, 0xac, 0x6e, 0x91, - 0xb2, 0xde, 0xa2, 0x65, 0xdd, 0xb6, 0x19, 0x17, 0xc4, 0xd0, 0xb1, 0xd3, 0x92, 0x2a, 0x56, 0x35, - 0x6f, 0xb5, 0xac, 0xdb, 0x9b, 0x21, 0x29, 0x30, 0xa2, 0x05, 0xc8, 0x83, 0x85, 0x24, 0x15, 0xbb, - 0xa5, 0x38, 0x6d, 0x12, 0x97, 0xeb, 0xcd, 0x56, 0x08, 0xa0, 0x9b, 0xc1, 0xf4, 0x9c, 0xa4, 0x53, - 0xfd, 0xe2, 0xd1, 0x62, 0x2e, 0x4d, 0xb0, 0x5f, 0xeb, 0xc3, 0x4e, 0xc5, 0x53, 0xfa, 0x98, 0x68, - 0x0e, 0x31, 0x98, 0x63, 0x06, 0x62, 0xf8, 0x57, 0x0a, 0x8c, 0xaf, 0xb8, 0xc4, 0x59, 0x96, 0xda, - 0x5c, 0x95, 0xac, 0x7b, 0xc4, 0xe5, 0xe8, 0x12, 0xbc, 0xa4, 0x9b, 0xa6, 0x43, 0x5c, 0x77, 0x4a, - 0x39, 0xaf, 0x4c, 0xe7, 0x2a, 0x68, 0xab, 0x5d, 0x3c, 0xb6, 0xa9, 0x37, 0xad, 0x9b, 0x58, 0x12, - 0xb0, 0x1a, 0xb2, 0xa0, 0x8b, 0xf0, 0x52, 0x8b, 0x31, 0x4b, 0xa3, 0xe6, 0xd4, 0xc8, 0x79, 0x65, - 0xfa, 0x40, 0x92, 0x5b, 0x12, 0xb0, 0x7a, 0xc8, 0xff, 0x56, 0x35, 0xd1, 0x02, 0x40, 0x9c, 0x82, - 0xa9, 0xfd, 0xe7, 0x95, 0xe9, 0x23, 0x97, 0xbf, 0x52, 0x92, 0xd1, 0xf3, 0xf3, 0x55, 0x0a, 0x76, - 0xa0, 0xcc, 0x57, 0x69, 0x59, 0xaf, 0x13, 0xe9, 0x96, 0x9a, 0x90, 0xc4, 0xbf, 0x55, 0xe0, 0x54, - 0x97, 0xef, 0x6e, 0x8b, 0xd9, 0x2e, 0x41, 0xef, 0x42, 0x2e, 0x0c, 0x8f, 0xef, 0xfe, 0xfe, 0xe9, - 0x23, 0x97, 0x6f, 0x97, 0x32, 0xed, 0xe4, 0xd2, 0x82, 0x67, 0x59, 0xa1, 0xc2, 0x8a, 0x43, 0xf4, - 0x86, 0xc9, 0x36, 0xec, 0xca, 0x81, 0x67, 0xed, 0xe2, 0x3e, 0x35, 0x56, 0x8a, 0xee, 0x75, 0x60, - 0x18, 0x11, 0x18, 0x5e, 0xe9, 0x8b, 0x21, 0x70, 0xaf, 0x03, 0xc4, 0x12, 0x8c, 0x45, 0xe6, 0x36, - 0xab, 0x66, 0x18, 0xfe, 0xeb, 0x70, 0x24, 0x34, 0xe6, 0x07, 0x55, 0x11, 0x41, 0x9d, 0xd8, 0x6a, - 0x17, 0x51, 0x18, 0xd4, 0x88, 0x88, 0x55, 0x08, 0x57, 0x55, 0x13, 0x3f, 0x86, 0xf1, 0x4e, 0x7d, - 0x32, 0x24, 0xdf, 0x86, 0xc3, 0x21, 0x97, 0xd0, 0xb6, 0x37, 0x11, 0x89, 0x74, 0xe2, 0xaf, 0xc3, - 0xe8, 0x32, 0x63, 0x56, 0xb4, 0x7f, 0x16, 0x52, 0x02, 0x34, 0x4c, 0x92, 0x7f, 0xa0, 0xc0, 0x51, - 0xa9, 0x58, 0x22, 0xb9, 0x06, 0x07, 0xfd, 0x8d, 0x14, 0x26, 0x76, 0xbc, 0x14, 0x1c, 0xa4, 0x52, - 0x78, 0x90, 0x4a, 0xb3, 0xf6, 0x66, 0x25, 0xf7, 0xfb, 0x5f, 0xce, 0x1c, 0xf4, 0xe5, 0xaa, 0x6a, - 0xc0, 0xbd, 0x77, 0x19, 0x3b, 0x0e, 0x47, 0x97, 0x45, 0xe1, 0x92, 0xee, 0xe2, 0x15, 0x38, 0x16, - 0x3e, 0x90, 0x2e, 0xce, 0xc1, 0xa1, 0xa0, 0xb6, 0xc9, 0x50, 0x5f, 0xe8, 0x13, 0xea, 0x40, 0x5c, - 0xc6, 0x54, 0x8a, 0xe2, 0x8f, 0x15, 0x38, 0xf1, 0x88, 0x1a, 0x8d, 0xc5, 0x90, 0x6d, 0x89, 0x70, - 0xf4, 0x2e, 0x1c, 0x8d, 0xc4, 0x34, 0x9b, 0x70, 0x79, 0x38, 0x6f, 0xf9, 0x92, 0x9f, 0xb5, 0x8b, - 0x67, 0x02, 0x3c, 0xae, 0xd9, 0x28, 0x51, 0x56, 0x6e, 0xea, 0x7c, 0xad, 0xb4, 0x48, 0xea, 0xba, - 0xb1, 0x39, 0x4f, 0x8c, 0xad, 0x76, 0x71, 0x3c, 0xd8, 0x3c, 0x1d, 0x1a, 0xb0, 0x3a, 0x6a, 0x25, - 0x2d, 0x5c, 0x05, 0xf0, 0x4b, 0xad, 0x46, 0x6d, 0x93, 0x3c, 0x11, 0x71, 0xda, 0x5f, 0x39, 0xb5, - 0xd5, 0x2e, 0x9e, 0x0c, 0x64, 0x63, 0x1a, 0x56, 0x73, 0x41, 0x4d, 0xf6, 0xbf, 0xff, 0x43, 0x81, - 0xc9, 0xc8, 0xd1, 0x79, 0xd2, 0xe2, 0x6b, 0xdf, 0xa0, 0x7c, 0x4d, 0xd5, 0xed, 0x3a, 0x41, 0xab, - 0x70, 0x22, 0xb6, 0xa8, 0x37, 0x99, 0x67, 0xef, 0x89, 0xdb, 0xc7, 0xa3, 0xf5, 0xac, 0xd0, 0xe9, - 0x7b, 0x6e, 0xb1, 0x0d, 0xe2, 0x68, 0xbe, 0x5b, 0xdb, 0x3d, 0x8f, 0x69, 0x58, 0xcd, 0x89, 0x85, - 0x1f, 0x5d, 0x5f, 0xca, 0x6b, 0xb5, 0x42, 0xa9, 0xfd, 0xdd, 0x52, 0x31, 0x0d, 0xab, 0x39, 0xb1, - 0xf0, 0xa5, 0xf0, 0xe7, 0x23, 0x50, 0x48, 0x26, 0xa6, 0x6a, 0xcf, 0x53, 0x87, 0x18, 0xfe, 0x06, - 0x09, 0x4f, 0x40, 0xa2, 0x26, 0x2a, 0x7d, 0x6b, 0x62, 0x09, 0x0e, 0x73, 0xd6, 0x20, 0xb6, 0x46, - 0x83, 0xbd, 0x99, 0xab, 0x8c, 0x6d, 0xb5, 0x8b, 0xc7, 0x65, 0xcc, 0x25, 0x05, 0xab, 0x2f, 0x89, - 0xaf, 0x55, 0xdb, 0xf7, 0xda, 0xe5, 0xba, 0xc3, 0x7b, 0x78, 0x1d, 0xd3, 0xb0, 0x9a, 0x13, 0x0b, - 0x81, 0xf5, 0x06, 0x8c, 0x7a, 0x2e, 0xd1, 0x0c, 0x4f, 0xa2, 0x3d, 0x70, 0x5e, 0x99, 0x3e, 0x5c, - 0x99, 0xdc, 0x6a, 0x17, 0xc7, 0x24, 0xda, 0x04, 0x15, 0xab, 0xe0, 0xb9, 0x64, 0xce, 0x8b, 0xc2, - 0x54, 0x63, 0x9e, 0x6d, 0x06, 0x82, 0x07, 0xbb, 0x0d, 0xc6, 0x34, 0xac, 0xe6, 0xc4, 0x22, 0x69, - 0xd0, 0x66, 0x9a, 0x78, 0x36, 0x75, 0x28, 0xcd, 0x60, 0x48, 0x0d, 0x0c, 0x2e, 0xb1, 0x8a, 0x58, - 0xfc, 0x74, 0x3f, 0x14, 0x7b, 0x46, 0x58, 0x9e, 0xb3, 0xb5, 0xe4, 0xce, 0x32, 0xfd, 0x5d, 0x17, - 0x56, 0x85, 0xeb, 0x19, 0x8b, 0x5b, 0xf7, 0x01, 0x93, 0x67, 0x30, 0xde, 0x5b, 0x62, 0x2f, 0xbb, - 0xe8, 0x65, 0x18, 0x35, 0x3c, 0xc7, 0x21, 0x36, 0x4f, 0xec, 0x2e, 0xf5, 0x88, 0x7c, 0x26, 0xb0, - 0x5a, 0x70, 0x32, 0x64, 0x89, 0xa4, 0x45, 0x66, 0x72, 0x95, 0xbb, 0xd9, 0xf6, 0xf9, 0x54, 0x10, - 0x93, 0x6d, 0x5a, 0xb0, 0x7a, 0x42, 0x3e, 0x8b, 0x5c, 0x45, 0x1f, 0x28, 0x80, 0x42, 0x46, 0x77, - 0xdd, 0xe1, 0x5a, 0xcb, 0xa1, 0x06, 0x11, 0x19, 0xcd, 0x55, 0x1e, 0x49, 0x7b, 0xe5, 0x3a, 0xe5, - 0x6b, 0x5e, 0xad, 0x64, 0xb0, 0x66, 0x59, 0xc6, 0x63, 0xc6, 0xd2, 0x6b, 0x6e, 0xb8, 0x10, 0x9f, - 0xc2, 0x8d, 0x0a, 0xad, 0x07, 0x3e, 0x9c, 0xee, 0xf4, 0x21, 0x56, 0x1d, 0x3b, 0xf1, 0x70, 0xdd, - 0xe1, 0xcb, 0xe2, 0xd1, 0xdb, 0x70, 0x36, 0xf2, 0x68, 0x39, 0x38, 0x19, 0xe2, 0xc8, 0x0f, 0x73, - 0x04, 0xf0, 0x87, 0x0a, 0x9c, 0xeb, 0xa1, 0x4d, 0xa6, 0xbb, 0x06, 0xb9, 0x38, 0xb2, 0x41, 0x9e, - 0xdf, 0xc8, 0x98, 0xe7, 0x1e, 0xb5, 0x29, 0x7c, 0xb1, 0xc7, 0xa1, 0xfe, 0x26, 0x9c, 0x9b, 0xb3, - 0x74, 0xda, 0xd4, 0x6b, 0x16, 0x79, 0xd8, 0x72, 0x88, 0x6e, 0xaa, 0x64, 0x43, 0x77, 0x4c, 0x77, - 0xd7, 0x6f, 0xe6, 0x9f, 0x28, 0x50, 0xe8, 0xa5, 0x5a, 0x02, 0xfc, 0x2e, 0x4c, 0x19, 0x21, 0x87, - 0xe6, 0x0a, 0x16, 0xcd, 0x09, 0x78, 0x24, 0xde, 0xd3, 0x1d, 0x6f, 0xac, 0x10, 0xdd, 0x1c, 0xa3, - 0x76, 0xe5, 0x15, 0x1f, 0xca, 0x56, 0xbb, 0x58, 0x94, 0x19, 0xec, 0xa1, 0x08, 0xab, 0x13, 0x46, - 0xaa, 0x17, 0x78, 0x05, 0xf2, 0x91, 0x7f, 0xd5, 0xf0, 0xba, 0xb8, 0x7b, 0xdc, 0x1f, 0x8e, 0xc0, - 0x99, 0x54, 0xbd, 0x12, 0xf4, 0x3a, 0x8c, 0xc7, 0xbe, 0x46, 0xd7, 0xd4, 0x0c, 0x80, 0xbf, 0x24, - 0x01, 0x9f, 0xe9, 0x06, 0x1c, 0x2b, 0xc1, 0xea, 0x98, 0xb1, 0xdd, 0xb4, 0x6f, 0x72, 0x95, 0x39, - 0xab, 0x84, 0x72, 0x62, 0x26, 0x4d, 0x8e, 0x0c, 0x68, 0x32, 0x4d, 0x09, 0x56, 0xc7, 0xa2, 0xc7, - 0xb1, 0x49, 0xbc, 0x08, 0xe7, 0xfc, 0xeb, 0xc8, 0xac, 0x61, 0x78, 0x4d, 0xcf, 0xd2, 0x39, 0x73, - 0xba, 0xf6, 0xd5, 0x40, 0x67, 0xe5, 0x37, 0x23, 0x50, 0xe8, 0xa5, 0x4e, 0x86, 0xf5, 0x23, 0x05, - 0xce, 0x74, 0x64, 0x5e, 0xab, 0x3b, 0x6c, 0x83, 0xaf, 0x69, 0x75, 0x8b, 0xd5, 0x74, 0x4b, 0x86, - 0xf7, 0x6c, 0x2a, 0xd6, 0x79, 0x62, 0x08, 0xb8, 0x57, 0x7c, 0xb8, 0x1f, 0x7f, 0x5e, 0xbc, 0x98, - 0xa8, 0x23, 0xb2, 0xaf, 0x0a, 0x3e, 0x66, 0x5c, 0xb3, 0x51, 0xe6, 0x9b, 0x2d, 0xe2, 0x86, 0x32, - 0xae, 0x3a, 0xe5, 0x26, 0x76, 0xd5, 0x3d, 0x61, 0xf3, 0x9e, 0x30, 0x89, 0xbe, 0xa7, 0xc0, 0xb8, - 0xd7, 0xf2, 0x1b, 0xa1, 0x2e, 0x5f, 0x82, 0xb8, 0x5f, 0xcd, 0x78, 0x96, 0x57, 0x84, 0x8a, 0x47, - 0x8e, 0x6e, 0x34, 0x88, 0xd3, 0x9d, 0x92, 0x34, 0xfd, 0x58, 0x45, 0xc1, 0xe3, 0xa4, 0x37, 0x7e, - 0xbd, 0x29, 0xf8, 0x35, 0x26, 0x11, 0x43, 0xa9, 0x73, 0xa8, 0x9c, 0x0c, 0x79, 0x71, 0xfa, 0x62, - 0x04, 0x8a, 0x3d, 0xbd, 0x90, 0xa9, 0x7c, 0xa6, 0xc0, 0x8d, 0xd4, 0x54, 0xb2, 0x96, 0x38, 0x67, - 0x44, 0x33, 0xc3, 0x57, 0xa3, 0xc6, 0x56, 0x35, 0x4b, 0x77, 0xb9, 0xc6, 0x1d, 0xfd, 0x31, 0x71, - 0xdc, 0xff, 0x65, 0xa2, 0x2f, 0x6f, 0x4f, 0xf4, 0x3b, 0xd2, 0xa1, 0xe8, 0x55, 0xfd, 0xce, 0xea, - 0xa2, 0xee, 0xf2, 0x47, 0xa1, 0x33, 0xe8, 0x29, 0x1c, 0x97, 0x19, 0xe2, 0x12, 0xe5, 0xae, 0x92, - 0x5f, 0x90, 0xc9, 0x9f, 0xe8, 0x48, 0x7e, 0xa8, 0x1a, 0xab, 0xc7, 0xbc, 0x24, 0xbb, 0x8b, 0xbf, - 0xaf, 0xc0, 0x64, 0x74, 0x28, 0x55, 0xd1, 0x08, 0x0f, 0x97, 0xec, 0xbd, 0x6a, 0x6f, 0x3e, 0x51, - 0x60, 0x6a, 0xbb, 0x43, 0x32, 0xef, 0x14, 0x4e, 0x76, 0xb7, 0xed, 0x61, 0x59, 0xfc, 0x6a, 0xc6, - 0x70, 0x75, 0xe9, 0x96, 0xef, 0xbb, 0x13, 0xb4, 0xcb, 0xe4, 0xde, 0x75, 0x47, 0xef, 0x2b, 0x70, - 0x71, 0x6e, 0xe1, 0xfe, 0x7d, 0xd1, 0x7b, 0x99, 0x8b, 0xd4, 0x6e, 0x2c, 0x38, 0xac, 0x39, 0x97, - 0x70, 0x32, 0xa0, 0x84, 0x51, 0x7f, 0x00, 0xe3, 0x49, 0x04, 0x5a, 0x67, 0x0a, 0x8a, 0x89, 0xf2, - 0x9e, 0xc2, 0x85, 0x55, 0x64, 0x6c, 0xd3, 0x8c, 0x29, 0x5c, 0xca, 0xe6, 0x81, 0x0c, 0xf3, 0x0d, - 0x18, 0x35, 0x56, 0x9b, 0xcd, 0x2e, 0xd3, 0x89, 0x4b, 0x6a, 0x92, 0x8a, 0x55, 0xf0, 0x97, 0xd2, - 0xd4, 0x7d, 0x38, 0xb7, 0xe2, 0x12, 0x67, 0xc5, 0xae, 0x31, 0xdb, 0xa4, 0x76, 0x7d, 0x77, 0x63, - 0x14, 0xfc, 0x33, 0x05, 0x0a, 0xbd, 0xf4, 0x49, 0x67, 0xdf, 0x57, 0x20, 0x1f, 0x8d, 0x21, 0xb4, - 0x0d, 0xca, 0xd7, 0xb4, 0x16, 0x71, 0x28, 0x33, 0x35, 0x8b, 0x19, 0x0d, 0xb9, 0x3b, 0xee, 0x64, - 0xdc, 0x1d, 0xa1, 0x7a, 0xff, 0x3e, 0xb4, 0x2c, 0xb4, 0x2c, 0x32, 0xa3, 0x21, 0x37, 0xc9, 0x64, - 0x64, 0xa6, 0x93, 0x8c, 0xf3, 0x30, 0x75, 0x8f, 0xf0, 0x47, 0x8c, 0xeb, 0x56, 0x74, 0xad, 0x0a, - 0x7b, 0xe1, 0x1f, 0x2a, 0x70, 0x3a, 0x85, 0x28, 0x9d, 0xe7, 0x70, 0x9c, 0xfb, 0x14, 0xad, 0xfb, - 0x1a, 0xb7, 0xc3, 0x2b, 0xf7, 0x35, 0x59, 0x9a, 0xa6, 0x33, 0x94, 0xa6, 0xa0, 0x2e, 0x1d, 0xe3, - 0x1d, 0xd6, 0xf1, 0x96, 0x02, 0x85, 0x25, 0xaf, 0xb9, 0x44, 0x9e, 0xf0, 0xaa, 0x4d, 0x39, 0xd5, - 0x2d, 0xfa, 0x1d, 0x22, 0xfa, 0x93, 0xe1, 0xce, 0xfe, 0x5d, 0x38, 0x16, 0x76, 0x64, 0x9a, 0x49, - 0x6c, 0xd6, 0x94, 0x1d, 0xdb, 0xe9, 0xad, 0x76, 0xf1, 0x54, 0x67, 0xc7, 0x16, 0xd0, 0xb1, 0x3a, - 0x2a, 0xfb, 0xb6, 0x79, 0x7f, 0x89, 0x6a, 0x90, 0xb7, 0xbd, 0xa6, 0x66, 0x93, 0x27, 0x5c, 0xa3, - 0xb1, 0x47, 0xa2, 0xb3, 0x70, 0x45, 0xcb, 0x70, 0xa0, 0x72, 0x61, 0xab, 0x5d, 0x7c, 0x39, 0x50, - 0xd6, 0x9b, 0x17, 0xab, 0x93, 0x76, 0x3a, 0x30, 0xfc, 0xe3, 0x11, 0x28, 0xf6, 0x04, 0xfd, 0x7f, - 0xdf, 0x3e, 0x5d, 0xfe, 0x57, 0x1e, 0x0e, 0x3e, 0xf0, 0x2b, 0x1a, 0xfa, 0xb9, 0x02, 0x62, 0x50, - 0xe4, 0xa2, 0x2b, 0x99, 0x4f, 0x4d, 0x3c, 0xe7, 0xca, 0x5f, 0x1d, 0x4c, 0x28, 0x88, 0x3c, 0xbe, - 0xfa, 0xc1, 0x1f, 0xfe, 0xfa, 0xa3, 0x91, 0x12, 0xba, 0x54, 0x4e, 0x1b, 0xdb, 0xc6, 0x53, 0xdb, - 0x68, 0x64, 0x2d, 0x1c, 0xfc, 0x85, 0x02, 0x87, 0x82, 0x51, 0x11, 0xca, 0x6c, 0x36, 0x39, 0xa9, - 0xca, 0x5f, 0x1b, 0x50, 0x4a, 0x7a, 0x7b, 0x4d, 0x78, 0x5b, 0x46, 0x33, 0x59, 0xbd, 0x0d, 0x7c, - 0xfc, 0x44, 0x81, 0xa3, 0x1d, 0xf3, 0x59, 0x74, 0x2b, 0xeb, 0x4b, 0x3e, 0x65, 0x22, 0x9d, 0xbf, - 0x3d, 0x9c, 0xb0, 0xc4, 0x50, 0x11, 0x18, 0x6e, 0xa3, 0x9b, 0x99, 0x23, 0x2e, 0x35, 0x94, 0xdf, - 0x93, 0xd5, 0xf9, 0x29, 0xfa, 0x42, 0x81, 0x53, 0xa9, 0x1d, 0x2a, 0x9a, 0x1b, 0xb4, 0x0d, 0x4d, - 0xe9, 0x96, 0xf3, 0xf3, 0xbb, 0x53, 0x22, 0x81, 0xde, 0x13, 0x40, 0x67, 0xd1, 0xdd, 0x8c, 0x40, - 0xe3, 0x0a, 0x10, 0x0e, 0xba, 0x34, 0x47, 0x60, 0xfa, 0x77, 0x72, 0xa4, 0xd7, 0x39, 0x80, 0x41, - 0x6f, 0x0d, 0xea, 0x6a, 0xea, 0x88, 0x2c, 0xbf, 0xb0, 0x5b, 0x35, 0x12, 0x73, 0x55, 0x60, 0x9e, - 0x43, 0xb3, 0x03, 0x63, 0xb6, 0x09, 0x17, 0x65, 0x3a, 0x42, 0xf6, 0x4f, 0x05, 0x26, 0xd2, 0xbb, - 0x74, 0x94, 0x35, 0x3f, 0x3b, 0xce, 0x0f, 0xf2, 0x6f, 0xed, 0x52, 0xcb, 0x90, 0x69, 0xee, 0x35, - 0x0e, 0x40, 0x7f, 0x51, 0x60, 0x2c, 0xa5, 0x3d, 0x47, 0xb3, 0x83, 0xfa, 0xb9, 0x6d, 0x64, 0x90, - 0xaf, 0xec, 0x46, 0x85, 0xc4, 0x39, 0x27, 0x70, 0xde, 0x41, 0xb7, 0x06, 0xc6, 0x19, 0xb7, 0xe4, - 0xe8, 0x77, 0x0a, 0x8c, 0x26, 0x7f, 0x15, 0x41, 0x37, 0x07, 0xbc, 0x20, 0x25, 0x7e, 0x9a, 0xc9, - 0xdf, 0x1a, 0x4a, 0x56, 0xc2, 0xb9, 0x23, 0xe0, 0x5c, 0x47, 0xd7, 0x06, 0x2c, 0x43, 0x5a, 0x6d, - 0x53, 0xa3, 0x26, 0xfa, 0x9b, 0x02, 0x13, 0xe9, 0x7d, 0x7f, 0xe6, 0xdd, 0xb9, 0xe3, 0x14, 0x22, - 0xf3, 0xee, 0xdc, 0x79, 0xf8, 0x80, 0x67, 0x05, 0xcc, 0x5b, 0xe8, 0xc6, 0x00, 0xef, 0x37, 0x4d, - 0xf7, 0xf5, 0x45, 0xfb, 0xf2, 0x8f, 0x0a, 0x9c, 0xe8, 0xee, 0x8c, 0xd0, 0x1b, 0xc3, 0xb5, 0x3d, - 0x11, 0xbc, 0xbb, 0x43, 0xcb, 0x4b, 0x60, 0x6f, 0x0a, 0x60, 0x37, 0xd1, 0xd7, 0x32, 0x02, 0xdb, - 0xd6, 0xbf, 0xa1, 0xbf, 0x2b, 0x30, 0xd9, 0xa3, 0xe1, 0xcf, 0x5c, 0x56, 0x77, 0x1e, 0x5b, 0x64, - 0x2e, 0xab, 0x7d, 0xe6, 0x0e, 0x03, 0xbf, 0x33, 0xc5, 0xcb, 0x23, 0xc8, 0x62, 0xd8, 0x82, 0xa3, - 0x5f, 0x8f, 0xc0, 0x97, 0xb3, 0x74, 0x63, 0x48, 0xcd, 0x5a, 0x2c, 0xb2, 0x37, 0x97, 0xf9, 0x87, - 0x7b, 0xaa, 0x53, 0x46, 0x85, 0x8a, 0xa8, 0x18, 0x48, 0xcf, 0x5a, 0x91, 0x12, 0xdd, 0xa3, 0x66, - 0x51, 0xbb, 0xa1, 0xad, 0x3a, 0xac, 0xa9, 0x25, 0x85, 0xca, 0xef, 0xa5, 0x75, 0xb7, 0x4f, 0xd1, - 0x7f, 0x14, 0x98, 0x48, 0xef, 0x07, 0x33, 0x1f, 0xf7, 0x1d, 0xdb, 0xd3, 0xcc, 0xc7, 0x7d, 0xe7, - 0xa6, 0x14, 0x3f, 0x10, 0x21, 0x79, 0x1b, 0x55, 0x33, 0x86, 0xc4, 0x73, 0x89, 0xa3, 0x79, 0xa1, - 0x3e, 0x2d, 0xed, 0xae, 0xf5, 0x99, 0x02, 0x27, 0xb7, 0x35, 0x92, 0x28, 0xeb, 0xf9, 0xed, 0xd5, - 0x9f, 0xe6, 0xdf, 0x1c, 0x5e, 0xc1, 0x90, 0x87, 0xa2, 0x4e, 0xb8, 0xd6, 0xd5, 0xf4, 0x8a, 0xab, - 0x55, 0x8f, 0xe6, 0x2c, 0x73, 0x0d, 0xd8, 0xb9, 0xa3, 0xcd, 0x5c, 0x03, 0xfa, 0xf4, 0x88, 0x03, - 0x5f, 0xad, 0x7a, 0x37, 0xab, 0x95, 0xb5, 0x67, 0xcf, 0x0b, 0xca, 0xa7, 0xcf, 0x0b, 0xca, 0x9f, - 0x9f, 0x17, 0x94, 0x8f, 0x5e, 0x14, 0xf6, 0x7d, 0xfa, 0xa2, 0xb0, 0xef, 0x4f, 0x2f, 0x0a, 0xfb, - 0xbe, 0xb5, 0xd4, 0xef, 0x77, 0xaa, 0xc7, 0x97, 0x5f, 0x2b, 0x3f, 0xe9, 0xf5, 0xd7, 0x16, 0xc3, - 0xa2, 0xc4, 0xe6, 0xc1, 0x9f, 0x7c, 0x82, 0x3f, 0x01, 0x1c, 0x12, 0x1f, 0x57, 0xfe, 0x1b, 0x00, - 0x00, 0xff, 0xff, 0x60, 0xdc, 0x43, 0xf3, 0xea, 0x24, 0x00, 0x00, + 0xa7, 0x9c, 0xc8, 0xd9, 0xf7, 0xfb, 0xbd, 0x37, 0xf3, 0x76, 0xde, 0x23, 0xe1, 0x15, 0xe6, 0x36, + 0x99, 0x6b, 0xba, 0x65, 0x9d, 0xd9, 0x3a, 0xb5, 0xb9, 0xa3, 0x71, 0x6a, 0xcc, 0x58, 0xe6, 0xba, + 0x67, 0x1a, 0x26, 0xdf, 0x28, 0xaf, 0x7b, 0xd4, 0xd9, 0x28, 0xb5, 0x1c, 0xc6, 0x19, 0x3e, 0x2f, + 0x79, 0x4b, 0x49, 0xde, 0x88, 0xb5, 0xf4, 0xe8, 0xb5, 0x1a, 0xe5, 0xda, 0x6b, 0xf9, 0xf1, 0x3a, + 0xab, 0x33, 0x21, 0x51, 0xf6, 0xbf, 0x05, 0xc2, 0xf9, 0x0b, 0x7d, 0x0c, 0xb5, 0x34, 0x47, 0x6b, + 0xba, 0x92, 0x79, 0xa6, 0x0f, 0x33, 0x37, 0xf5, 0x46, 0xd5, 0x5e, 0x0d, 0x75, 0x17, 0x74, 0xc1, + 0x5f, 0xae, 0x69, 0x2e, 0x2d, 0x4b, 0x37, 0xca, 0x3a, 0x33, 0x6d, 0x49, 0x7f, 0x25, 0x49, 0x17, + 0x88, 0x22, 0xae, 0x96, 0x56, 0x37, 0x6d, 0x8d, 0x9b, 0x2c, 0xe4, 0x3d, 0x53, 0x67, 0xac, 0x6e, + 0xd1, 0xb2, 0xd6, 0x32, 0xcb, 0x9a, 0x6d, 0x33, 0x2e, 0x88, 0xa1, 0x63, 0xa7, 0x24, 0x55, 0xac, + 0x6a, 0xde, 0x6a, 0x59, 0xb3, 0x37, 0x42, 0x52, 0x60, 0x44, 0x0d, 0x90, 0x07, 0x0b, 0x49, 0x2a, + 0x76, 0x4b, 0x71, 0xb3, 0x49, 0x5d, 0xae, 0x35, 0x5b, 0x21, 0x80, 0x6e, 0x06, 0xc3, 0x73, 0x92, + 0x4e, 0xf5, 0x8b, 0x47, 0x8b, 0xb9, 0x66, 0x82, 0xfd, 0x6a, 0x1f, 0x76, 0x53, 0x3c, 0x35, 0x1f, + 0x51, 0xd5, 0xa1, 0x3a, 0x73, 0x8c, 0x40, 0x8c, 0xfc, 0x0a, 0xc1, 0xf8, 0x8a, 0x4b, 0x9d, 0x65, + 0xa9, 0xcd, 0x55, 0xe8, 0xba, 0x47, 0x5d, 0x8e, 0x2f, 0xc2, 0x41, 0xcd, 0x30, 0x1c, 0xea, 0xba, + 0x53, 0xe8, 0x1c, 0x9a, 0xce, 0x55, 0xf0, 0x66, 0xbb, 0x78, 0x74, 0x43, 0x6b, 0x5a, 0x37, 0x88, + 0x24, 0x10, 0x25, 0x64, 0xc1, 0x17, 0xe0, 0x60, 0x8b, 0x31, 0x4b, 0x35, 0x8d, 0xa9, 0x91, 0x73, + 0x68, 0x7a, 0x5f, 0x92, 0x5b, 0x12, 0x88, 0x72, 0xc0, 0xff, 0x56, 0x35, 0xf0, 0x02, 0x40, 0x9c, + 0x82, 0xa9, 0xbd, 0xe7, 0xd0, 0xf4, 0xe1, 0x4b, 0x5f, 0x29, 0xc9, 0xe8, 0xf9, 0xf9, 0x2a, 0x05, + 0x3b, 0x50, 0xe6, 0xab, 0xb4, 0xac, 0xd5, 0xa9, 0x74, 0x4b, 0x49, 0x48, 0x92, 0xdf, 0x21, 0x38, + 0xd9, 0xe5, 0xbb, 0xdb, 0x62, 0xb6, 0x4b, 0xf1, 0x3b, 0x90, 0x0b, 0xc3, 0xe3, 0xbb, 0xbf, 0x77, + 0xfa, 0xf0, 0xa5, 0x5b, 0xa5, 0x4c, 0x3b, 0xb9, 0xb4, 0xe0, 0x59, 0x56, 0xa8, 0xb0, 0xe2, 0x50, + 0xad, 0x61, 0xb0, 0xc7, 0x76, 0x65, 0xdf, 0xb3, 0x76, 0x71, 0x8f, 0x12, 0x2b, 0xc5, 0x77, 0x3b, + 0x30, 0x8c, 0x08, 0x0c, 0x2f, 0xf7, 0xc5, 0x10, 0xb8, 0xd7, 0x01, 0x62, 0x09, 0xc6, 0x22, 0x73, + 0x1b, 0x55, 0x23, 0x0c, 0xff, 0x35, 0x38, 0x1c, 0x1a, 0xf3, 0x83, 0x8a, 0x44, 0x50, 0x27, 0x36, + 0xdb, 0x45, 0x1c, 0x06, 0x35, 0x22, 0x12, 0x05, 0xc2, 0x55, 0xd5, 0x20, 0x8f, 0x60, 0xbc, 0x53, + 0x9f, 0x0c, 0xc9, 0xb7, 0xe1, 0x50, 0xc8, 0x25, 0xb4, 0xed, 0x4e, 0x44, 0x22, 0x9d, 0xe4, 0xeb, + 0x30, 0xba, 0xcc, 0x98, 0x15, 0xed, 0x9f, 0x85, 0x94, 0x00, 0x0d, 0x93, 0xe4, 0x1f, 0x20, 0x38, + 0x22, 0x15, 0x4b, 0x24, 0x57, 0x61, 0xbf, 0xbf, 0x91, 0xc2, 0xc4, 0x8e, 0x97, 0x82, 0x83, 0x54, + 0x0a, 0x0f, 0x52, 0x69, 0xd6, 0xde, 0xa8, 0xe4, 0xfe, 0xf0, 0xcb, 0x99, 0xfd, 0xbe, 0x5c, 0x55, + 0x09, 0xb8, 0x77, 0x2f, 0x63, 0xc7, 0xe0, 0xc8, 0xb2, 0x28, 0x5c, 0xd2, 0x5d, 0xb2, 0x02, 0x47, + 0xc3, 0x07, 0xd2, 0xc5, 0x39, 0x38, 0x10, 0xd4, 0x36, 0x19, 0xea, 0xf3, 0x7d, 0x42, 0x1d, 0x88, + 0xcb, 0x98, 0x4a, 0x51, 0xf2, 0x11, 0x82, 0xe3, 0x0f, 0x4d, 0xbd, 0xb1, 0x18, 0xb2, 0x2d, 0x51, + 0x8e, 0xdf, 0x81, 0x23, 0x91, 0x98, 0x6a, 0x53, 0x2e, 0x0f, 0xe7, 0x4d, 0x5f, 0xf2, 0xd3, 0x76, + 0xf1, 0x74, 0x80, 0xc7, 0x35, 0x1a, 0x25, 0x93, 0x95, 0x9b, 0x1a, 0x5f, 0x2b, 0x2d, 0xd2, 0xba, + 0xa6, 0x6f, 0xcc, 0x53, 0x7d, 0xb3, 0x5d, 0x1c, 0x0f, 0x36, 0x4f, 0x87, 0x06, 0xa2, 0x8c, 0x5a, + 0x49, 0x0b, 0x57, 0x00, 0xfc, 0x52, 0xab, 0x9a, 0xb6, 0x41, 0x9f, 0x88, 0x38, 0xed, 0xad, 0x9c, + 0xdc, 0x6c, 0x17, 0x4f, 0x04, 0xb2, 0x31, 0x8d, 0x28, 0xb9, 0xa0, 0x26, 0xfb, 0xdf, 0xff, 0x89, + 0x60, 0x32, 0x72, 0x74, 0x9e, 0xb6, 0xf8, 0xda, 0x37, 0x4c, 0xbe, 0xa6, 0x68, 0x76, 0x9d, 0xe2, + 0x55, 0x38, 0x1e, 0x5b, 0xd4, 0x9a, 0xcc, 0xb3, 0x77, 0xc5, 0xed, 0x63, 0xd1, 0x7a, 0x56, 0xe8, + 0xf4, 0x3d, 0xb7, 0xd8, 0x63, 0xea, 0xa8, 0xbe, 0x5b, 0x5b, 0x3d, 0x8f, 0x69, 0x44, 0xc9, 0x89, + 0x85, 0x1f, 0x5d, 0x5f, 0xca, 0x6b, 0xb5, 0x42, 0xa9, 0xbd, 0xdd, 0x52, 0x31, 0x8d, 0x28, 0x39, + 0xb1, 0xf0, 0xa5, 0xc8, 0x67, 0x23, 0x50, 0x48, 0x26, 0xa6, 0x6a, 0xcf, 0x9b, 0x0e, 0xd5, 0xfd, + 0x0d, 0x12, 0x9e, 0x80, 0x44, 0x4d, 0x44, 0x7d, 0x6b, 0x62, 0x09, 0x0e, 0x71, 0xd6, 0xa0, 0xb6, + 0x6a, 0x06, 0x7b, 0x33, 0x57, 0x19, 0xdb, 0x6c, 0x17, 0x8f, 0xc9, 0x98, 0x4b, 0x0a, 0x51, 0x0e, + 0x8a, 0xaf, 0x55, 0xdb, 0xf7, 0xda, 0xe5, 0x9a, 0xc3, 0x7b, 0x78, 0x1d, 0xd3, 0x88, 0x92, 0x13, + 0x0b, 0x81, 0xf5, 0x3a, 0x8c, 0x7a, 0x2e, 0x55, 0x75, 0x4f, 0xa2, 0xdd, 0x77, 0x0e, 0x4d, 0x1f, + 0xaa, 0x4c, 0x6e, 0xb6, 0x8b, 0x63, 0x12, 0x6d, 0x82, 0x4a, 0x14, 0xf0, 0x5c, 0x3a, 0xe7, 0x45, + 0x61, 0xaa, 0x31, 0xcf, 0x36, 0x02, 0xc1, 0xfd, 0xdd, 0x06, 0x63, 0x1a, 0x51, 0x72, 0x62, 0x91, + 0x34, 0x68, 0x33, 0x55, 0x3c, 0x9b, 0x3a, 0x90, 0x66, 0x30, 0xa4, 0x06, 0x06, 0x97, 0x58, 0x45, + 0x2c, 0x7e, 0xba, 0x17, 0x8a, 0x3d, 0x23, 0x2c, 0xcf, 0xd9, 0x5a, 0x72, 0x67, 0x19, 0xfe, 0xae, + 0x0b, 0xab, 0xc2, 0xb5, 0x8c, 0xc5, 0xad, 0xfb, 0x80, 0xc9, 0x33, 0x18, 0xef, 0x2d, 0xb1, 0x97, + 0x5d, 0xfc, 0x12, 0x8c, 0xea, 0x9e, 0xe3, 0x50, 0x9b, 0x27, 0x76, 0x97, 0x72, 0x58, 0x3e, 0x13, + 0x58, 0x2d, 0x38, 0x11, 0xb2, 0x44, 0xd2, 0x22, 0x33, 0xb9, 0xca, 0x9d, 0x6c, 0xfb, 0x7c, 0x2a, + 0x88, 0xc9, 0x16, 0x2d, 0x44, 0x39, 0x2e, 0x9f, 0x45, 0xae, 0xe2, 0xf7, 0x11, 0xe0, 0x90, 0xd1, + 0x5d, 0x77, 0xb8, 0xda, 0x72, 0x4c, 0x9d, 0x8a, 0x8c, 0xe6, 0x2a, 0x0f, 0xa5, 0xbd, 0x72, 0xdd, + 0xe4, 0x6b, 0x5e, 0xad, 0xa4, 0xb3, 0x66, 0x59, 0xc6, 0x63, 0xc6, 0xd2, 0x6a, 0x6e, 0xb8, 0x10, + 0x9f, 0xc2, 0x8d, 0x8a, 0x59, 0x0f, 0x7c, 0x38, 0xd5, 0xe9, 0x43, 0xac, 0x3a, 0x76, 0xe2, 0xc1, + 0xba, 0xc3, 0x97, 0xc5, 0xa3, 0xb7, 0xe0, 0x4c, 0xe4, 0xd1, 0x72, 0x70, 0x32, 0xc4, 0x91, 0x1f, + 0xe6, 0x08, 0x90, 0xdf, 0x20, 0x38, 0xdb, 0x43, 0x9b, 0x4c, 0x77, 0x0d, 0x72, 0x71, 0x64, 0x83, + 0x3c, 0xbf, 0x9e, 0x31, 0xcf, 0x3d, 0x6a, 0x53, 0xf8, 0x62, 0x8f, 0x04, 0xf0, 0x0d, 0x18, 0xad, + 0x79, 0x7a, 0x83, 0xf2, 0x8e, 0x02, 0x98, 0xd8, 0xb1, 0x49, 0x2a, 0x51, 0x0e, 0x07, 0xcb, 0xa0, + 0x08, 0x7e, 0x13, 0xce, 0xce, 0x59, 0x9a, 0xd9, 0xd4, 0x6a, 0x16, 0x7d, 0xd0, 0x72, 0xa8, 0x66, + 0x28, 0xf4, 0xb1, 0xe6, 0x18, 0xee, 0x8e, 0xdf, 0xea, 0x3f, 0x41, 0x50, 0xe8, 0xa5, 0x5a, 0x06, + 0xe7, 0xbb, 0x30, 0xa5, 0x87, 0x1c, 0xaa, 0x2b, 0x58, 0x54, 0x27, 0xe0, 0x91, 0xb1, 0x3a, 0xd5, + 0xf1, 0xb6, 0x0b, 0x23, 0x33, 0xc7, 0x4c, 0xbb, 0xf2, 0xb2, 0x1f, 0x86, 0xcd, 0x76, 0xb1, 0x28, + 0xb3, 0xdf, 0x43, 0x11, 0x51, 0x26, 0xf4, 0x54, 0x2f, 0xc8, 0x0a, 0xe4, 0x23, 0xff, 0xaa, 0xe1, + 0x55, 0x73, 0xe7, 0xb8, 0x3f, 0x18, 0x81, 0xd3, 0xa9, 0x7a, 0x25, 0xe8, 0x75, 0x18, 0x8f, 0x7d, + 0x8d, 0xae, 0xb8, 0x19, 0x00, 0x7f, 0x49, 0x02, 0x3e, 0xdd, 0x0d, 0x38, 0x56, 0x42, 0x94, 0x31, + 0x7d, 0xab, 0x69, 0xdf, 0xe4, 0x2a, 0x73, 0x56, 0xa9, 0xc9, 0xa9, 0x91, 0x34, 0x39, 0x32, 0xa0, + 0xc9, 0x34, 0x25, 0x44, 0x19, 0x8b, 0x1e, 0xc7, 0x26, 0xc9, 0x22, 0x9c, 0xf5, 0xaf, 0x32, 0xb3, + 0xba, 0xee, 0x35, 0x3d, 0x4b, 0xe3, 0xcc, 0xe9, 0xda, 0x57, 0x03, 0x9d, 0xb3, 0xdf, 0x8e, 0x40, + 0xa1, 0x97, 0x3a, 0x19, 0xd6, 0x0f, 0x11, 0x9c, 0xee, 0xc8, 0xbc, 0x5a, 0x77, 0xd8, 0x63, 0xbe, + 0xa6, 0xd6, 0x2d, 0x56, 0xd3, 0x2c, 0x19, 0xde, 0x33, 0xa9, 0x58, 0xe7, 0xa9, 0x2e, 0xe0, 0x5e, + 0xf6, 0xe1, 0x7e, 0xf4, 0x59, 0xf1, 0x42, 0xa2, 0x06, 0xc9, 0x9e, 0x2c, 0xf8, 0x98, 0x71, 0x8d, + 0x46, 0x99, 0x6f, 0xb4, 0xa8, 0x1b, 0xca, 0xb8, 0xca, 0x94, 0x9b, 0xd8, 0x55, 0x77, 0x85, 0xcd, + 0xbb, 0xc2, 0x24, 0xfe, 0x1e, 0x82, 0x71, 0xaf, 0xe5, 0x37, 0x51, 0x5d, 0xbe, 0x04, 0x71, 0xbf, + 0x92, 0xb1, 0x0e, 0xac, 0x08, 0x15, 0x0f, 0x1d, 0x4d, 0x6f, 0x50, 0xa7, 0x3b, 0x25, 0x69, 0xfa, + 0x89, 0x82, 0x83, 0xc7, 0x49, 0x6f, 0xc8, 0x07, 0x08, 0x0a, 0x7e, 0x7d, 0x4a, 0xc4, 0x50, 0xea, + 0x1c, 0x2a, 0x27, 0x43, 0x5e, 0xba, 0x3e, 0x1f, 0x81, 0x62, 0x4f, 0x2f, 0x64, 0x2a, 0x9f, 0x21, + 0xb8, 0x9e, 0x9a, 0x4a, 0xd6, 0x12, 0xe7, 0x8c, 0xaa, 0x46, 0xf8, 0x5a, 0x55, 0xd9, 0xaa, 0x6a, + 0x69, 0x2e, 0x57, 0xb9, 0xa3, 0x3d, 0xa2, 0x8e, 0xfb, 0xff, 0x4c, 0xf4, 0xa5, 0xad, 0x89, 0x7e, + 0x5b, 0x3a, 0x14, 0xbd, 0xe6, 0xdf, 0x5e, 0x5d, 0xd4, 0x5c, 0xfe, 0x30, 0x74, 0x06, 0x3f, 0x85, + 0x63, 0x32, 0x43, 0x5c, 0xa2, 0xdc, 0x51, 0xf2, 0x0b, 0x32, 0xf9, 0x13, 0x1d, 0xc9, 0x0f, 0x55, + 0x13, 0xe5, 0xa8, 0x97, 0x64, 0x77, 0xc9, 0xf7, 0x11, 0x4c, 0x46, 0x87, 0x52, 0x11, 0x4d, 0xf4, + 0x70, 0xc9, 0xde, 0xad, 0xd6, 0xe8, 0x63, 0x04, 0x53, 0x5b, 0x1d, 0x92, 0x79, 0x37, 0xe1, 0x44, + 0x77, 0xcb, 0x1f, 0x96, 0xc5, 0xaf, 0x66, 0x0c, 0x57, 0x97, 0x6e, 0xf9, 0xae, 0x3c, 0x6e, 0x76, + 0x99, 0xdc, 0xbd, 0xce, 0xea, 0x3d, 0x04, 0x17, 0xe6, 0x16, 0xee, 0xdd, 0x13, 0x7d, 0x9b, 0xb1, + 0x68, 0xda, 0x8d, 0x05, 0x87, 0x35, 0xe7, 0x12, 0x4e, 0x06, 0x94, 0x30, 0xea, 0xf7, 0x61, 0x3c, + 0x89, 0x40, 0xed, 0x4c, 0x41, 0x31, 0x51, 0xde, 0x53, 0xb8, 0x88, 0x82, 0xf5, 0x2d, 0x9a, 0x89, + 0x09, 0x17, 0xb3, 0x79, 0x20, 0xc3, 0x7c, 0x1d, 0x46, 0xf5, 0xd5, 0x66, 0xb3, 0xcb, 0x74, 0xe2, + 0xba, 0x90, 0xa4, 0x12, 0x05, 0xfc, 0xa5, 0x34, 0x75, 0x0f, 0xce, 0xae, 0xb8, 0xd4, 0x59, 0xb1, + 0x6b, 0xcc, 0x36, 0x4c, 0xbb, 0xbe, 0xb3, 0x11, 0x0c, 0xf9, 0x19, 0x82, 0x42, 0x2f, 0x7d, 0xd2, + 0xd9, 0xf7, 0x10, 0xe4, 0xa3, 0x11, 0x86, 0xfa, 0xd8, 0xe4, 0x6b, 0x6a, 0x8b, 0x3a, 0x26, 0x33, + 0x54, 0x8b, 0xe9, 0x0d, 0xb9, 0x3b, 0x6e, 0x67, 0xdc, 0x1d, 0xa1, 0x7a, 0xff, 0x2e, 0xb5, 0x2c, + 0xb4, 0x2c, 0x32, 0xbd, 0x21, 0x37, 0xc9, 0x64, 0x64, 0xa6, 0x93, 0x4c, 0xf2, 0x30, 0x75, 0x97, + 0xf2, 0x87, 0x8c, 0x6b, 0x56, 0x74, 0x25, 0x0b, 0xfb, 0xe8, 0x1f, 0x22, 0x38, 0x95, 0x42, 0x94, + 0xce, 0x73, 0x38, 0xc6, 0x7d, 0x8a, 0xda, 0x7d, 0x05, 0xdc, 0xe6, 0x95, 0xfb, 0xaa, 0x2c, 0x4d, + 0xd3, 0x19, 0x4a, 0x53, 0x50, 0x97, 0x8e, 0xf2, 0x0e, 0xeb, 0x64, 0x13, 0x41, 0x61, 0xc9, 0x6b, + 0x2e, 0xd1, 0x27, 0xbc, 0x6a, 0x9b, 0xdc, 0xd4, 0x2c, 0xf3, 0x3b, 0x54, 0xf4, 0x36, 0xc3, 0x9d, + 0xfd, 0x3b, 0x70, 0x34, 0xec, 0xe6, 0x54, 0x83, 0xda, 0xac, 0x29, 0xbb, 0xbd, 0x53, 0x9b, 0xed, + 0xe2, 0xc9, 0xce, 0x6e, 0x2f, 0xa0, 0x13, 0x65, 0x54, 0xf6, 0x7c, 0xf3, 0xfe, 0x12, 0xd7, 0x20, + 0x6f, 0x7b, 0x4d, 0xd5, 0xa6, 0x4f, 0xfc, 0x3b, 0x68, 0xe4, 0x91, 0xe8, 0x4a, 0x5c, 0xd1, 0x6e, + 0xec, 0xab, 0x9c, 0xdf, 0x6c, 0x17, 0x5f, 0x0a, 0x94, 0xf5, 0xe6, 0x25, 0xca, 0xa4, 0x9d, 0x0e, + 0x8c, 0xfc, 0x78, 0x04, 0x8a, 0x3d, 0x41, 0x7f, 0xe1, 0x5b, 0xaf, 0x4b, 0xff, 0xce, 0xc3, 0xfe, + 0xfb, 0x7e, 0x45, 0xc3, 0x3f, 0x47, 0x20, 0x86, 0x4c, 0x2e, 0xbe, 0x9c, 0xf9, 0xd4, 0xc4, 0x33, + 0xb2, 0xfc, 0x95, 0xc1, 0x84, 0x82, 0xc8, 0x93, 0x2b, 0xef, 0xff, 0xf1, 0x6f, 0x3f, 0x1a, 0x29, + 0xe1, 0x8b, 0xe5, 0xb4, 0x91, 0x6f, 0x3c, 0xf1, 0x8d, 0xc6, 0xdd, 0xc2, 0xc1, 0x5f, 0x20, 0x38, + 0x10, 0x8c, 0x99, 0x70, 0x66, 0xb3, 0xc9, 0x29, 0x57, 0xfe, 0xea, 0x80, 0x52, 0xd2, 0xdb, 0xab, + 0xc2, 0xdb, 0x32, 0x9e, 0xc9, 0xea, 0x6d, 0xe0, 0xe3, 0xc7, 0x08, 0x8e, 0x74, 0xcc, 0x76, 0xf1, + 0xcd, 0xac, 0x2f, 0xf9, 0x94, 0x69, 0x76, 0xfe, 0xd6, 0x70, 0xc2, 0x12, 0x43, 0x45, 0x60, 0xb8, + 0x85, 0x6f, 0x64, 0x8e, 0xb8, 0xd4, 0x50, 0x7e, 0x57, 0x56, 0xe7, 0xa7, 0xf8, 0x73, 0x04, 0x27, + 0x53, 0xbb, 0x5b, 0x3c, 0x37, 0x68, 0x0b, 0x9b, 0xd2, 0x69, 0xe7, 0xe7, 0x77, 0xa6, 0x44, 0x02, + 0xbd, 0x2b, 0x80, 0xce, 0xe2, 0x3b, 0x19, 0x81, 0xc6, 0x15, 0x20, 0x1c, 0x92, 0xa9, 0x8e, 0xc0, + 0xf4, 0x9f, 0xe4, 0x38, 0xb0, 0x73, 0x78, 0x83, 0xdf, 0x1c, 0xd4, 0xd5, 0xd4, 0xf1, 0x5a, 0x7e, + 0x61, 0xa7, 0x6a, 0x24, 0xe6, 0xaa, 0xc0, 0x3c, 0x87, 0x67, 0x07, 0xc6, 0x6c, 0x8b, 0x31, 0x40, + 0x7c, 0x7f, 0xc6, 0xff, 0x42, 0x30, 0x91, 0xde, 0xa5, 0xe3, 0xac, 0xf9, 0xd9, 0x76, 0x7e, 0x90, + 0x7f, 0x73, 0x87, 0x5a, 0x86, 0x4c, 0x73, 0xaf, 0x71, 0x00, 0xfe, 0x2b, 0x82, 0xb1, 0x94, 0xf6, + 0x1c, 0xcf, 0x0e, 0xea, 0xe7, 0x96, 0x91, 0x41, 0xbe, 0xb2, 0x13, 0x15, 0x12, 0xe7, 0x9c, 0xc0, + 0x79, 0x1b, 0xdf, 0x1c, 0x18, 0x67, 0xdc, 0x92, 0xe3, 0xdf, 0x23, 0x18, 0x4d, 0xfe, 0xa2, 0x82, + 0x6f, 0x0c, 0x78, 0x41, 0x4a, 0xfc, 0xac, 0x93, 0xbf, 0x39, 0x94, 0xac, 0x84, 0x73, 0x5b, 0xc0, + 0xb9, 0x86, 0xaf, 0x0e, 0x58, 0x86, 0xd4, 0xda, 0x86, 0x6a, 0x1a, 0xf8, 0xef, 0x08, 0x26, 0xd2, + 0xfb, 0xfe, 0xcc, 0xbb, 0x73, 0xdb, 0x29, 0x44, 0xe6, 0xdd, 0xb9, 0xfd, 0xf0, 0x81, 0xcc, 0x0a, + 0x98, 0x37, 0xf1, 0xf5, 0x01, 0xde, 0x6f, 0xaa, 0xe6, 0xeb, 0x8b, 0xf6, 0xe5, 0x9f, 0x10, 0x1c, + 0xef, 0xee, 0x8c, 0xf0, 0xeb, 0xc3, 0xb5, 0x3d, 0x11, 0xbc, 0x3b, 0x43, 0xcb, 0x4b, 0x60, 0x6f, + 0x08, 0x60, 0x37, 0xf0, 0xd7, 0x32, 0x02, 0xdb, 0xd2, 0xbf, 0xe1, 0x7f, 0x20, 0x98, 0xec, 0xd1, + 0xf0, 0x67, 0x2e, 0xab, 0xdb, 0x8f, 0x2d, 0x32, 0x97, 0xd5, 0x3e, 0x73, 0x87, 0x81, 0xdf, 0x99, + 0xe2, 0xe5, 0x11, 0x64, 0x31, 0x6c, 0xc1, 0xf1, 0xaf, 0x47, 0xe0, 0xcb, 0x59, 0xba, 0x31, 0xac, + 0x64, 0x2d, 0x16, 0xd9, 0x9b, 0xcb, 0xfc, 0x83, 0x5d, 0xd5, 0x29, 0xa3, 0x62, 0x8a, 0xa8, 0xe8, + 0x58, 0xcb, 0x5a, 0x91, 0x12, 0xdd, 0xa3, 0x6a, 0x99, 0x76, 0x43, 0x5d, 0x75, 0x58, 0x53, 0x4d, + 0x0a, 0x95, 0xdf, 0x4d, 0xeb, 0x6e, 0x9f, 0xe2, 0xff, 0x22, 0x98, 0x48, 0xef, 0x07, 0x33, 0x1f, + 0xf7, 0x6d, 0xdb, 0xd3, 0xcc, 0xc7, 0x7d, 0xfb, 0xa6, 0x94, 0xdc, 0x17, 0x21, 0x79, 0x0b, 0x57, + 0x33, 0x86, 0xc4, 0x73, 0xa9, 0xa3, 0x7a, 0xa1, 0x3e, 0x35, 0xed, 0xae, 0xf5, 0x29, 0x82, 0x13, + 0x5b, 0x1a, 0x49, 0x9c, 0xf5, 0xfc, 0xf6, 0xea, 0x4f, 0xf3, 0x6f, 0x0c, 0xaf, 0x60, 0xc8, 0x43, + 0x51, 0xa7, 0x5c, 0xed, 0x6a, 0x7a, 0xc5, 0xd5, 0xaa, 0x47, 0x73, 0x96, 0xb9, 0x06, 0x6c, 0xdf, + 0xd1, 0x66, 0xae, 0x01, 0x7d, 0x7a, 0xc4, 0x81, 0xaf, 0x56, 0xbd, 0x9b, 0xd5, 0xca, 0xda, 0xb3, + 0xe7, 0x05, 0xf4, 0xc9, 0xf3, 0x02, 0xfa, 0xcb, 0xf3, 0x02, 0xfa, 0xf0, 0x45, 0x61, 0xcf, 0x27, + 0x2f, 0x0a, 0x7b, 0xfe, 0xfc, 0xa2, 0xb0, 0xe7, 0x5b, 0x4b, 0xfd, 0x7e, 0xe3, 0x7a, 0x74, 0xe9, + 0xd5, 0xf2, 0x93, 0x5e, 0x7f, 0x8b, 0xd1, 0x2d, 0x93, 0xda, 0x3c, 0xf8, 0x83, 0x50, 0xf0, 0x07, + 0x82, 0x03, 0xe2, 0xe3, 0xf2, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x38, 0x6e, 0x67, 0x5c, 0x26, + 0x25, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2997,6 +3007,11 @@ func (m *LiquidityPerTickRangeResponse) MarshalToSizedBuffer(dAtA []byte) (int, _ = i var l int _ = l + if m.BucketIndex != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.BucketIndex)) + i-- + dAtA[i] = 0x10 + } if len(m.Liquidity) > 0 { for iNdEx := len(m.Liquidity) - 1; iNdEx >= 0; iNdEx-- { { @@ -3915,6 +3930,9 @@ func (m *LiquidityPerTickRangeResponse) Size() (n int) { n += 1 + l + sovQuery(uint64(l)) } } + if m.BucketIndex != 0 { + n += 1 + sovQuery(uint64(m.BucketIndex)) + } return n } @@ -5658,6 +5676,25 @@ func (m *LiquidityPerTickRangeResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BucketIndex", wireType) + } + m.BucketIndex = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BucketIndex |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) diff --git a/x/concentrated-liquidity/query.go b/x/concentrated-liquidity/query.go index 57a61835612..bd12692931c 100644 --- a/x/concentrated-liquidity/query.go +++ b/x/concentrated-liquidity/query.go @@ -17,54 +17,77 @@ import ( types "github.com/osmosis-labs/osmosis/v20/x/concentrated-liquidity/types" ) +const invalidTickIndex = int64(-1) + // This file contains query-related helper functions for the Concentrated Liquidity module -// GetTickLiquidityForFullRange returns an array of liquidity depth for all ticks existing from min tick ~ max tick. -func (k Keeper) GetTickLiquidityForFullRange(ctx sdk.Context, poolId uint64) ([]queryproto.LiquidityDepthWithRange, error) { +// GetTickLiquidityForFullRange returns a slice of liquidity buckets for all tick ranges existing from min tick ~ max tick. +// Returns index of the bucket that corresponds to the current tick. +// For cases where there is no liqudity in the bucket but there may be liquidity to the right, the value will be -1. +// For cases where there is no liquidity in the bucket but there may be liquidity to the left, the value will be len(liquidityDepthsForRange). +// Otherwise, the index points to the bucket that corresponds to the current tick. +func (k Keeper) GetTickLiquidityForFullRange(ctx sdk.Context, poolId uint64) ([]queryproto.LiquidityDepthWithRange, int64, error) { // use false for zeroForOne since we're going from lower tick -> upper tick zeroForOne := false swapStrategy := swapstrategy.New(zeroForOne, osmomath.ZeroBigDec(), k.storeKey, osmomath.ZeroDec()) - // set current tick to min tick, and find the first initialized tick starting from min tick -1. + // set leftmost tick to min tick, and find the first initialized tick starting from min tick -1. // we do -1 to make min tick inclusive. - currentTick := types.MinCurrentTick + // Note that MinCurrentTick = MinInitializedTick - 1 + leftMostTickIndex := types.MinCurrentTick - nextTickIter := swapStrategy.InitializeNextTickIterator(ctx, poolId, currentTick) + nextTickIter := swapStrategy.InitializeNextTickIterator(ctx, poolId, leftMostTickIndex) defer nextTickIter.Close() if !nextTickIter.Valid() { - return []queryproto.LiquidityDepthWithRange{}, types.RanOutOfTicksForPoolError{PoolId: poolId} + return []queryproto.LiquidityDepthWithRange{}, invalidTickIndex, types.RanOutOfTicksForPoolError{PoolId: poolId} } nextTick, err := types.TickIndexFromBytes(nextTickIter.Key()) if err != nil { - return []queryproto.LiquidityDepthWithRange{}, err + return []queryproto.LiquidityDepthWithRange{}, invalidTickIndex, err } tick, err := k.getTickByTickIndex(ctx, poolId, nextTick) if err != nil { - return []queryproto.LiquidityDepthWithRange{}, err + return []queryproto.LiquidityDepthWithRange{}, invalidTickIndex, err } liquidityDepthsForRange := []queryproto.LiquidityDepthWithRange{} // use the smallest tick initialized as the starting point for calculating liquidity. currentLiquidity := tick.LiquidityNet - currentTick = nextTick + leftMostTickIndex = nextTick totalLiquidityWithinRange := currentLiquidity - previousTickIndex := currentTick + previousTickIndex := leftMostTickIndex + + concentratedPool, err := k.getPoolById(ctx, poolId) + if err != nil { + return []queryproto.LiquidityDepthWithRange{}, invalidTickIndex, err + } + + var ( + currentBucketIndex = invalidTickIndex + currentTick = concentratedPool.GetCurrentTick() + currentTickLiquidity = concentratedPool.GetLiquidity() + ) // start from the next index so that the current tick can become lower tick. nextTickIter.Next() for ; nextTickIter.Valid(); nextTickIter.Next() { tickIndex, err := types.TickIndexFromBytes(nextTickIter.Key()) if err != nil { - return []queryproto.LiquidityDepthWithRange{}, err + return []queryproto.LiquidityDepthWithRange{}, invalidTickIndex, err } tickStruct, err := ParseTickFromBz(nextTickIter.Value()) if err != nil { - return []queryproto.LiquidityDepthWithRange{}, err + return []queryproto.LiquidityDepthWithRange{}, invalidTickIndex, err + } + + // Found the current bucket, update its index. + if currentBucketIndex == invalidTickIndex && concentratedPool.IsCurrentTickInRange(previousTickIndex, tickIndex) && currentTickLiquidity.Equal(totalLiquidityWithinRange) { + currentBucketIndex = int64(len(liquidityDepthsForRange)) } liquidityDepthForRange := queryproto.LiquidityDepthWithRange{ @@ -80,7 +103,12 @@ func (k Keeper) GetTickLiquidityForFullRange(ctx sdk.Context, poolId uint64) ([] totalLiquidityWithinRange = totalLiquidityWithinRange.Add(currentLiquidity) } - return liquidityDepthsForRange, nil + // This signifies that currrent tick is above the max initialized tick + if currentTick >= previousTickIndex && currentTickLiquidity.IsZero() { + currentBucketIndex = int64(len(liquidityDepthsForRange)) + } + + return liquidityDepthsForRange, currentBucketIndex, nil } // GetLiquidityNetInDirection is a method that returns an array of TickLiquidityNet objects representing the net liquidity in a specified direction diff --git a/x/concentrated-liquidity/query_test.go b/x/concentrated-liquidity/query_test.go index a2e92772799..04bf6f705b7 100644 --- a/x/concentrated-liquidity/query_test.go +++ b/x/concentrated-liquidity/query_test.go @@ -1,27 +1,73 @@ package concentrated_liquidity_test import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/osmosis-labs/osmosis/osmomath" "github.com/osmosis-labs/osmosis/v20/x/concentrated-liquidity/client/queryproto" "github.com/osmosis-labs/osmosis/v20/x/concentrated-liquidity/math" "github.com/osmosis-labs/osmosis/v20/x/concentrated-liquidity/types/genesis" ) +// This test validates GetTickLiquidityForFullRange query by force-setting the tick and their net liquidity +// values as well as the current pool tick. +// It then checks if the returned range is as expected. func (s *KeeperTestSuite) TestGetTickLiquidityForFullRange() { defaultTick := withPoolId(defaultTick, defaultPoolId) - - tests := []struct { - name string - presetTicks []genesis.FullTick + type testcase struct { + name string + presetTicks []genesis.FullTick + currentTickIndex int64 expectedLiquidityDepthForRange []queryproto.LiquidityDepthWithRange - }{ + + // Current tick is always 0 so must be pointing to the appropriate bucket + // within which tick 0 is contained. + expectedCurrentBucketIndex int64 + } + + defaultUpperTick := int64(5) + + defaultCase := testcase{ + name: "one ranged position, testing range with greater range than initialized ticks", + presetTicks: []genesis.FullTick{ + withLiquidityNetandTickIndex(defaultTick, DefaultMinTick, osmomath.NewDec(10)), + withLiquidityNetandTickIndex(defaultTick, defaultUpperTick, osmomath.NewDec(-10)), + }, + expectedLiquidityDepthForRange: []queryproto.LiquidityDepthWithRange{ + { + LiquidityAmount: osmomath.NewDec(10), + LowerTick: DefaultMinTick, + UpperTick: defaultUpperTick, + }, + }, + } + + withCurrentTickAndBucketIndex := func(desiredCurrentTick, expectedCurrentBucketIndex int64, appendNameSuffix string) testcase { + // deep copy default case + test := testcase{ + name: defaultCase.name, + presetTicks: make([]genesis.FullTick, len(defaultCase.presetTicks)), + expectedLiquidityDepthForRange: make([]queryproto.LiquidityDepthWithRange, len(defaultCase.expectedLiquidityDepthForRange)), + } + copy(test.presetTicks, defaultCase.presetTicks) + copy(test.expectedLiquidityDepthForRange, defaultCase.expectedLiquidityDepthForRange) + + test.name = test.name + " " + appendNameSuffix + test.currentTickIndex = desiredCurrentTick + test.expectedCurrentBucketIndex = expectedCurrentBucketIndex + return test + } + + tests := []testcase{ { name: "one full range position, testing range in between", presetTicks: []genesis.FullTick{ withLiquidityNetandTickIndex(defaultTick, DefaultMinTick, osmomath.NewDec(10)), withLiquidityNetandTickIndex(defaultTick, DefaultMaxTick, osmomath.NewDec(-10)), }, + currentTickIndex: 100, + expectedLiquidityDepthForRange: []queryproto.LiquidityDepthWithRange{ { LiquidityAmount: osmomath.NewDec(10), @@ -29,21 +75,15 @@ func (s *KeeperTestSuite) TestGetTickLiquidityForFullRange() { UpperTick: DefaultMaxTick, }, }, + expectedCurrentBucketIndex: 0, }, - { - name: "one ranged position, testing range with greater range than initialized ticks", - presetTicks: []genesis.FullTick{ - withLiquidityNetandTickIndex(defaultTick, DefaultMinTick, osmomath.NewDec(10)), - withLiquidityNetandTickIndex(defaultTick, 5, osmomath.NewDec(-10)), - }, - expectedLiquidityDepthForRange: []queryproto.LiquidityDepthWithRange{ - { - LiquidityAmount: osmomath.NewDec(10), - LowerTick: DefaultMinTick, - UpperTick: 5, - }, - }, - }, + withCurrentTickAndBucketIndex(DefaultMinTick-1, -1, "current tick below min tick"), + withCurrentTickAndBucketIndex(DefaultMinTick, 0, "current tick at min tick"), + withCurrentTickAndBucketIndex(defaultUpperTick-1, 0, "current tick one below max"), + // Corresponds to length since the current tick is at the max tick + withCurrentTickAndBucketIndex(defaultUpperTick, int64(len(defaultCase.expectedLiquidityDepthForRange)), "current tick at max"), + // Corresponds to length since the current tick is above the max tick + withCurrentTickAndBucketIndex(defaultUpperTick+1, int64(len(defaultCase.expectedLiquidityDepthForRange)), "current tick above max"), // 10 ----------------- 30 // -20 ------------- 20 { @@ -54,6 +94,8 @@ func (s *KeeperTestSuite) TestGetTickLiquidityForFullRange() { withLiquidityNetandTickIndex(defaultTick, 10, osmomath.NewDec(50)), withLiquidityNetandTickIndex(defaultTick, 30, osmomath.NewDec(-50)), }, + currentTickIndex: 15, + expectedLiquidityDepthForRange: []queryproto.LiquidityDepthWithRange{ { LiquidityAmount: osmomath.NewDec(10), @@ -71,6 +113,8 @@ func (s *KeeperTestSuite) TestGetTickLiquidityForFullRange() { UpperTick: 30, }, }, + + expectedCurrentBucketIndex: 1, }, // 10 ----------------- 30 // min tick --------------------------------------max tick @@ -82,6 +126,8 @@ func (s *KeeperTestSuite) TestGetTickLiquidityForFullRange() { withLiquidityNetandTickIndex(defaultTick, 10, osmomath.NewDec(50)), withLiquidityNetandTickIndex(defaultTick, 30, osmomath.NewDec(-50)), }, + currentTickIndex: 30, + expectedLiquidityDepthForRange: []queryproto.LiquidityDepthWithRange{ { LiquidityAmount: osmomath.NewDec(10), @@ -99,6 +145,8 @@ func (s *KeeperTestSuite) TestGetTickLiquidityForFullRange() { UpperTick: DefaultMaxTick, }, }, + + expectedCurrentBucketIndex: 2, }, // 11--13 // 10 ----------------- 30 @@ -113,6 +161,8 @@ func (s *KeeperTestSuite) TestGetTickLiquidityForFullRange() { withLiquidityNetandTickIndex(defaultTick, 11, osmomath.NewDec(100)), withLiquidityNetandTickIndex(defaultTick, 13, osmomath.NewDec(-100)), }, + currentTickIndex: 30, + expectedLiquidityDepthForRange: []queryproto.LiquidityDepthWithRange{ { LiquidityAmount: osmomath.NewDec(10), @@ -140,6 +190,9 @@ func (s *KeeperTestSuite) TestGetTickLiquidityForFullRange() { UpperTick: 30, }, }, + + // Equals to length since current tick is above max tick + expectedCurrentBucketIndex: 5, }, } @@ -149,18 +202,111 @@ func (s *KeeperTestSuite) TestGetTickLiquidityForFullRange() { s.SetupTest() // Create a default CL pool - s.PrepareConcentratedPool() - for _, tick := range test.presetTicks { + concentratedPool := s.PrepareConcentratedPool() + // Set current tick to the configured value + concentratedPool.SetCurrentTick(test.currentTickIndex) + + currentTickLiquidity := osmomath.ZeroDec() + for i, tick := range test.presetTicks { + if i > 0 { + lowerTick := test.presetTicks[i-1].TickIndex + upperTick := tick.TickIndex + + // Set current liquidity corresponding to the appropriate bucket + if concentratedPool.IsCurrentTickInRange(lowerTick, upperTick) { + concentratedPool.UpdateLiquidity(currentTickLiquidity) + } + } + s.App.ConcentratedLiquidityKeeper.SetTickInfo(s.Ctx, tick.PoolId, tick.TickIndex, &tick.Info) + + currentTickLiquidity = currentTickLiquidity.Add(tick.Info.LiquidityNet) } - liquidityForRange, err := s.App.ConcentratedLiquidityKeeper.GetTickLiquidityForFullRange(s.Ctx, defaultPoolId) + // Write updates pool to state + err := s.App.ConcentratedLiquidityKeeper.SetPool(s.Ctx, concentratedPool) + s.Require().NoError(err) + + liquidityForRange, currentBucketIndex, err := s.App.ConcentratedLiquidityKeeper.GetTickLiquidityForFullRange(s.Ctx, defaultPoolId) s.Require().NoError(err) s.Require().Equal(liquidityForRange, test.expectedLiquidityDepthForRange) + + s.Require().Equal(test.expectedCurrentBucketIndex, currentBucketIndex) }) } } +// Tests GetTickLiquidityForFullRange by creating a position as opposed to directly +// setting tick net liquidity valies +func (s *KeeperTestSuite) TestGetTickLiquidityForFullRange_CreatePosition() { + // Init suite for each test. + s.SetupTest() + + var ( + positionOneLowerTick = int64(-500000) + posititionOneUpperTick = int64(500000) + + positionTwoLowerTick = int64(-100000) + positionTwoUpperTick = int64(1250000) + + defaultTokenAmount = osmomath.NewInt(1000000000000000000) + defaultToken0 = sdk.NewCoin(ETH, defaultTokenAmount) + defaultToken1 = sdk.NewCoin(USDC, defaultTokenAmount.MulRaw(5)) + defaultCoins = sdk.NewCoins(defaultToken0, defaultToken1) + + expectedLiquidityDepthForRange = []queryproto.LiquidityDepthWithRange{ + { + // This gets initializes after position creation + LiquidityAmount: osmomath.ZeroDec(), + LowerTick: positionOneLowerTick, + UpperTick: positionTwoLowerTick, + }, + { + // This gets initializes after position creation + LiquidityAmount: osmomath.ZeroDec(), + LowerTick: positionTwoLowerTick, + UpperTick: posititionOneUpperTick, + }, + { + // This gets initializes after position creation + LiquidityAmount: osmomath.ZeroDec(), + LowerTick: posititionOneUpperTick, + UpperTick: positionTwoUpperTick, + }, + } + + // points to the bucket between positionTwo lower tick and positionOne upper tick + expectedCurrentBucketIndex = int64(3) + ) + + // Create a default CL pool + concentratedPool := s.PrepareConcentratedPool() + + // Fund account with enough tokens for both positions + s.FundAcc(s.TestAccs[0], defaultCoins.Add(defaultCoins...)) + + // Create first position + positionOneData, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, concentratedPool.GetId(), s.TestAccs[0], defaultCoins, osmomath.ZeroInt(), osmomath.ZeroInt(), positionOneLowerTick, posititionOneUpperTick) + s.Require().NoError(err) + + // Create second position + positionTwoData, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, concentratedPool.GetId(), s.TestAccs[0], defaultCoins, osmomath.ZeroInt(), osmomath.ZeroInt(), positionTwoLowerTick, positionTwoUpperTick) + s.Require().NoError(err) + + s.Require().Len(expectedLiquidityDepthForRange, 3) + // We take CreatePosition as correct since it is tested for correctness at a lower level + // of abstraction + expectedLiquidityDepthForRange[0].LiquidityAmount = positionOneData.Liquidity + expectedLiquidityDepthForRange[1].LiquidityAmount = positionOneData.Liquidity.Add(positionTwoData.Liquidity) + expectedLiquidityDepthForRange[2].LiquidityAmount = positionTwoData.Liquidity + + liquidityForRange, currentBucketIndex, err := s.App.ConcentratedLiquidityKeeper.GetTickLiquidityForFullRange(s.Ctx, defaultPoolId) + s.Require().NoError(err) + s.Require().Equal(liquidityForRange, expectedLiquidityDepthForRange) + + s.Require().Equal(expectedCurrentBucketIndex, currentBucketIndex) +} + func (s *KeeperTestSuite) TestGetTickLiquidityNetInDirection() { defaultTick := withPoolId(defaultTick, defaultPoolId)