From 7ca28c2bf89da2527f2675137f93dc0657c2f4f5 Mon Sep 17 00:00:00 2001 From: sampocs Date: Fri, 15 Mar 2024 09:19:31 -0500 Subject: [PATCH 01/13] fixed misc lint errors --- x/stakeibc/keeper/icacallbacks_undelegate.go | 2 +- x/stakeibc/keeper/msg_server.go | 6 +++--- x/stakeibc/keeper/redemption_sweep.go | 5 ----- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/x/stakeibc/keeper/icacallbacks_undelegate.go b/x/stakeibc/keeper/icacallbacks_undelegate.go index 7c6877129a..f3f24e149f 100644 --- a/x/stakeibc/keeper/icacallbacks_undelegate.go +++ b/x/stakeibc/keeper/icacallbacks_undelegate.go @@ -187,7 +187,7 @@ func (k Keeper) UpdateHostZoneUnbondings( if !success { k.Logger(ctx).Error(fmt.Sprintf("Failed to set host zone epoch unbonding record: epochNumber %d, chainId %s, hostZoneUnbonding %+v", epochUnbondingRecord.EpochNumber, chainId, hostZoneUnbonding)) - return sdkmath.ZeroInt(), errorsmod.Wrapf(types.ErrEpochNotFound, "couldn't set host zone epoch unbonding record. err: %s", err.Error()) + return sdkmath.ZeroInt(), errorsmod.Wrapf(types.ErrEpochNotFound, "couldn't set host zone epoch unbonding record") } k.RecordsKeeper.SetEpochUnbondingRecord(ctx, *updatedEpochUnbondingRecord) diff --git a/x/stakeibc/keeper/msg_server.go b/x/stakeibc/keeper/msg_server.go index 40e06314e8..c93982a6a5 100644 --- a/x/stakeibc/keeper/msg_server.go +++ b/x/stakeibc/keeper/msg_server.go @@ -218,8 +218,8 @@ func (k msgServer) RegisterHostZone(goCtx context.Context, msg *types.MsgRegiste } updatedEpochUnbondingRecord, success := k.RecordsKeeper.AddHostZoneToEpochUnbondingRecord(ctx, epochUnbondingRecord.EpochNumber, chainId, hostZoneUnbonding) if !success { - errMsg := fmt.Sprintf("Failed to set host zone epoch unbonding record: epochNumber %d, chainId %s, hostZoneUnbonding %v. Err: %s", - epochUnbondingRecord.EpochNumber, chainId, hostZoneUnbonding, err.Error()) + errMsg := fmt.Sprintf("Failed to set host zone epoch unbonding record: epochNumber %d, chainId %s, hostZoneUnbonding %v", + epochUnbondingRecord.EpochNumber, chainId, hostZoneUnbonding) k.Logger(ctx).Error(errMsg) return nil, errorsmod.Wrapf(types.ErrEpochNotFound, errMsg) } @@ -616,7 +616,7 @@ func (k msgServer) RedeemStake(goCtx context.Context, msg *types.MsgRedeemStake) updatedEpochUnbondingRecord, success := k.RecordsKeeper.AddHostZoneToEpochUnbondingRecord(ctx, epochUnbondingRecord.EpochNumber, hostZone.ChainId, hostZoneUnbonding) if !success { k.Logger(ctx).Error(fmt.Sprintf("Failed to set host zone epoch unbonding record: epochNumber %d, chainId %s, hostZoneUnbonding %v", epochUnbondingRecord.EpochNumber, hostZone.ChainId, hostZoneUnbonding)) - return nil, errorsmod.Wrapf(types.ErrEpochNotFound, "couldn't set host zone epoch unbonding record. err: %s", err.Error()) + return nil, errorsmod.Wrapf(types.ErrEpochNotFound, "couldn't set host zone epoch unbonding record") } k.RecordsKeeper.SetEpochUnbondingRecord(ctx, *updatedEpochUnbondingRecord) diff --git a/x/stakeibc/keeper/redemption_sweep.go b/x/stakeibc/keeper/redemption_sweep.go index c8cd445c3a..28586e8198 100644 --- a/x/stakeibc/keeper/redemption_sweep.go +++ b/x/stakeibc/keeper/redemption_sweep.go @@ -49,11 +49,6 @@ func (k Keeper) SweepAllUnbondedTokensForHostZone(ctx sdk.Context, hostZone type if inTransferQueue && validUnbondingTime { k.Logger(ctx).Info(utils.LogWithHostZone(hostZone.ChainId, " %v%s included in sweep", hostZoneUnbonding.NativeTokenAmount, hostZoneUnbonding.Denom)) - if err != nil { - errMsg := fmt.Sprintf("Could not convert native token amount to int64 | %s", err.Error()) - k.Logger(ctx).Error(errMsg) - continue - } totalAmtTransferToRedemptionAcct = totalAmtTransferToRedemptionAcct.Add(hostZoneUnbonding.NativeTokenAmount) epochUnbondingRecordIds = append(epochUnbondingRecordIds, epochUnbondingRecord.EpochNumber) } From b756e8cca167f84906905fc671e8a1046c2288d0 Mon Sep 17 00:00:00 2001 From: sampocs Date: Fri, 15 Mar 2024 10:36:11 -0500 Subject: [PATCH 02/13] added rebate to protos --- proto/stride/stakeibc/host_zone.proto | 14 + x/stakeibc/types/host_zone.pb.go | 390 ++++++++++++++++++++++---- 2 files changed, 350 insertions(+), 54 deletions(-) diff --git a/proto/stride/stakeibc/host_zone.proto b/proto/stride/stakeibc/host_zone.proto index b22c3dae68..e000707945 100644 --- a/proto/stride/stakeibc/host_zone.proto +++ b/proto/stride/stakeibc/host_zone.proto @@ -7,6 +7,19 @@ import "cosmos_proto/cosmos.proto"; option go_package = "github.com/Stride-Labs/stride/v19/x/stakeibc/types"; +// CommunityPoolRebate stores the size of the community pool liquid stake +// and the rebate percentage +message CommunityPoolRebate { + string rebate_percentage = 1 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + string liquid_stake_amount = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; +} + message HostZone { string chain_id = 1; string bech32prefix = 17; @@ -70,6 +83,7 @@ message HostZone { (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false ]; + CommunityPoolRebate community_pool_rebate = 34; bool lsm_liquid_stake_enabled = 27; bool halted = 19; reserved 4, 5, 6, 7, 14, 15, 16; diff --git a/x/stakeibc/types/host_zone.pb.go b/x/stakeibc/types/host_zone.pb.go index 42a6fa0c9a..27fdf5b6a8 100644 --- a/x/stakeibc/types/host_zone.pb.go +++ b/x/stakeibc/types/host_zone.pb.go @@ -25,6 +25,46 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +// CommunityPoolRebate stores the size of the community pool liquid stake +// and the rebate percentage +type CommunityPoolRebate struct { + RebatePercentage github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,1,opt,name=rebate_percentage,json=rebatePercentage,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"rebate_percentage"` + LiquidStakeAmount github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=liquid_stake_amount,json=liquidStakeAmount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"liquid_stake_amount"` +} + +func (m *CommunityPoolRebate) Reset() { *m = CommunityPoolRebate{} } +func (m *CommunityPoolRebate) String() string { return proto.CompactTextString(m) } +func (*CommunityPoolRebate) ProtoMessage() {} +func (*CommunityPoolRebate) Descriptor() ([]byte, []int) { + return fileDescriptor_f81bf5b42c61245a, []int{0} +} +func (m *CommunityPoolRebate) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CommunityPoolRebate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CommunityPoolRebate.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *CommunityPoolRebate) XXX_Merge(src proto.Message) { + xxx_messageInfo_CommunityPoolRebate.Merge(m, src) +} +func (m *CommunityPoolRebate) XXX_Size() int { + return m.Size() +} +func (m *CommunityPoolRebate) XXX_DiscardUnknown() { + xxx_messageInfo_CommunityPoolRebate.DiscardUnknown(m) +} + +var xxx_messageInfo_CommunityPoolRebate proto.InternalMessageInfo + type HostZone struct { ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` Bech32Prefix string `protobuf:"bytes,17,opt,name=bech32prefix,proto3" json:"bech32prefix,omitempty"` @@ -52,6 +92,7 @@ type HostZone struct { MaxRedemptionRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,21,opt,name=max_redemption_rate,json=maxRedemptionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"max_redemption_rate"` MinInnerRedemptionRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,28,opt,name=min_inner_redemption_rate,json=minInnerRedemptionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"min_inner_redemption_rate"` MaxInnerRedemptionRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,29,opt,name=max_inner_redemption_rate,json=maxInnerRedemptionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"max_inner_redemption_rate"` + CommunityPoolRebate *CommunityPoolRebate `protobuf:"bytes,34,opt,name=community_pool_rebate,json=communityPoolRebate,proto3" json:"community_pool_rebate,omitempty"` LsmLiquidStakeEnabled bool `protobuf:"varint,27,opt,name=lsm_liquid_stake_enabled,json=lsmLiquidStakeEnabled,proto3" json:"lsm_liquid_stake_enabled,omitempty"` Halted bool `protobuf:"varint,19,opt,name=halted,proto3" json:"halted,omitempty"` } @@ -60,7 +101,7 @@ func (m *HostZone) Reset() { *m = HostZone{} } func (m *HostZone) String() string { return proto.CompactTextString(m) } func (*HostZone) ProtoMessage() {} func (*HostZone) Descriptor() ([]byte, []int) { - return fileDescriptor_f81bf5b42c61245a, []int{0} + return fileDescriptor_f81bf5b42c61245a, []int{1} } func (m *HostZone) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -208,6 +249,13 @@ func (m *HostZone) GetCommunityPoolRedeemHoldingAddress() string { return "" } +func (m *HostZone) GetCommunityPoolRebate() *CommunityPoolRebate { + if m != nil { + return m.CommunityPoolRebate + } + return nil +} + func (m *HostZone) GetLsmLiquidStakeEnabled() bool { if m != nil { return m.LsmLiquidStakeEnabled @@ -223,66 +271,115 @@ func (m *HostZone) GetHalted() bool { } func init() { + proto.RegisterType((*CommunityPoolRebate)(nil), "stride.stakeibc.CommunityPoolRebate") proto.RegisterType((*HostZone)(nil), "stride.stakeibc.HostZone") } func init() { proto.RegisterFile("stride/stakeibc/host_zone.proto", fileDescriptor_f81bf5b42c61245a) } var fileDescriptor_f81bf5b42c61245a = []byte{ - // 835 bytes of a gzipped FileDescriptorProto + // 922 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x96, 0xcf, 0x6e, 0xdb, 0x36, - 0x18, 0xc0, 0xe3, 0x55, 0x4d, 0x14, 0xb6, 0x89, 0x65, 0xc5, 0xf5, 0x94, 0x74, 0x71, 0x9c, 0xec, - 0x0f, 0xb2, 0x43, 0x6c, 0x2c, 0x3d, 0x0c, 0x1b, 0x76, 0x58, 0x3b, 0x0f, 0xa8, 0x8d, 0xa0, 0x28, - 0x14, 0x60, 0x87, 0xee, 0x20, 0x50, 0xe2, 0x67, 0x8b, 0xab, 0x44, 0x7a, 0x24, 0xdd, 0xb8, 0x7b, - 0x8a, 0x3d, 0x4c, 0x1f, 0xa2, 0xc7, 0xa2, 0xbb, 0x0c, 0x3b, 0x14, 0x43, 0xf2, 0x22, 0x83, 0x28, - 0xc9, 0x96, 0xad, 0x0c, 0x42, 0x01, 0x9f, 0x22, 0x7e, 0x7f, 0x7e, 0x3f, 0x7d, 0x14, 0x15, 0x0b, - 0x1d, 0x49, 0x25, 0x28, 0x81, 0x9e, 0x54, 0xf8, 0x25, 0x50, 0x3f, 0xe8, 0x85, 0x5c, 0x2a, 0xef, - 0x0f, 0xce, 0xa0, 0x3b, 0x11, 0x5c, 0x71, 0xbb, 0x9e, 0x16, 0x74, 0xf3, 0x82, 0x83, 0x52, 0xc7, - 0x2b, 0x1c, 0x51, 0x82, 0x15, 0x17, 0x69, 0xc7, 0x41, 0x73, 0xcc, 0xc7, 0x5c, 0x5f, 0xf6, 0x92, - 0xab, 0x2c, 0xba, 0x1f, 0x70, 0x19, 0x73, 0xe9, 0xa5, 0x89, 0x74, 0x91, 0xa6, 0x4e, 0xfe, 0xaa, - 0x23, 0xf3, 0x29, 0x97, 0xea, 0x05, 0x67, 0x60, 0xef, 0x23, 0x33, 0x08, 0x31, 0x65, 0x1e, 0x25, - 0x4e, 0xad, 0x53, 0x3b, 0xdd, 0x76, 0xb7, 0xf4, 0x7a, 0x40, 0xec, 0x13, 0x74, 0xdf, 0x87, 0x20, - 0x7c, 0x74, 0x3e, 0x11, 0x30, 0xa2, 0x33, 0xa7, 0xa1, 0xd3, 0x4b, 0x31, 0xfb, 0x73, 0xb4, 0x13, - 0x70, 0xc6, 0x20, 0x50, 0x94, 0x6b, 0xc6, 0x27, 0x69, 0xd1, 0x22, 0x38, 0x20, 0x76, 0x17, 0xed, - 0x29, 0x81, 0x99, 0x1c, 0x81, 0xf0, 0x82, 0x10, 0x33, 0x06, 0x51, 0x52, 0x7a, 0x5f, 0x97, 0x36, - 0xf2, 0xd4, 0x4f, 0x69, 0x66, 0x40, 0xec, 0x87, 0x68, 0x9b, 0xfa, 0x81, 0x47, 0x80, 0xf1, 0xd8, - 0x31, 0x75, 0x95, 0x49, 0xfd, 0xa0, 0x9f, 0xac, 0xed, 0x43, 0x84, 0xf4, 0x9e, 0xa5, 0xd9, 0x6d, - 0x9d, 0xdd, 0x4e, 0x22, 0x69, 0xfa, 0x6b, 0x64, 0x4d, 0x99, 0xcf, 0x19, 0xa1, 0x6c, 0xec, 0x4d, - 0x40, 0x50, 0x4e, 0x9c, 0x83, 0x4e, 0xed, 0xd4, 0x70, 0xeb, 0xf3, 0xf8, 0x73, 0x1d, 0xb6, 0xbf, - 0x47, 0x68, 0xbe, 0x97, 0xd2, 0xb9, 0xd3, 0xb9, 0x73, 0x7a, 0xef, 0xfc, 0xa0, 0xbb, 0xb2, 0xff, - 0xdd, 0x5f, 0xf2, 0x12, 0xb7, 0x50, 0x6d, 0x3f, 0x46, 0x75, 0x02, 0x13, 0x2e, 0xa9, 0xf2, 0x30, - 0x21, 0x02, 0xa4, 0x74, 0xec, 0xe4, 0x56, 0x9e, 0x38, 0xef, 0xdf, 0x9c, 0x35, 0xb3, 0xed, 0x7e, - 0x9c, 0x66, 0x2e, 0x95, 0xa0, 0x6c, 0xec, 0xee, 0x66, 0x0d, 0x59, 0xd4, 0x7e, 0x86, 0x5a, 0x57, - 0x54, 0x85, 0x44, 0xe0, 0x2b, 0x1c, 0x79, 0x34, 0xc0, 0x73, 0x52, 0xab, 0x82, 0xd4, 0x5c, 0xf4, - 0x0d, 0x02, 0x9c, 0xf3, 0x7e, 0x44, 0xf5, 0x11, 0xc0, 0x12, 0xe8, 0xd3, 0x0a, 0xd0, 0xce, 0x08, - 0xa0, 0x40, 0x78, 0x86, 0x5a, 0x04, 0x22, 0x18, 0xe3, 0xf4, 0x61, 0x16, 0x40, 0x4e, 0xd5, 0x1d, - 0x2d, 0xfa, 0x96, 0x79, 0x02, 0x08, 0xc4, 0x93, 0x12, 0x6f, 0xbf, 0x8a, 0xb7, 0xe8, 0x2b, 0xf0, - 0x08, 0x3a, 0x09, 0x78, 0x1c, 0x4f, 0x19, 0x55, 0xaf, 0xbd, 0x09, 0xe7, 0x91, 0x97, 0x3f, 0x83, - 0x22, 0xbb, 0x5d, 0xc1, 0x6e, 0xcf, 0x19, 0xcf, 0x39, 0x8f, 0xfa, 0x29, 0xa1, 0x60, 0xf1, 0xd1, - 0xf1, 0x8a, 0x45, 0x80, 0x9a, 0x8a, 0xe5, 0x01, 0x8e, 0x2a, 0x24, 0x87, 0x4b, 0x12, 0x57, 0x03, - 0x0a, 0x8e, 0x10, 0x7d, 0xb1, 0xe2, 0xd0, 0xe7, 0xcd, 0x0b, 0x79, 0xa4, 0x0f, 0x6e, 0xae, 0xe9, - 0x54, 0x68, 0x3a, 0x4b, 0x9a, 0xcb, 0x84, 0xf1, 0x34, 0x45, 0xe4, 0xa6, 0xdf, 0xd0, 0x97, 0xa5, - 0x69, 0x08, 0x40, 0x5c, 0x52, 0x1d, 0x57, 0xa8, 0x8e, 0x57, 0x26, 0x4a, 0x20, 0x2b, 0xae, 0x5f, - 0x51, 0x43, 0x71, 0x85, 0x93, 0xc7, 0x92, 0x9f, 0x06, 0xe9, 0xec, 0x68, 0x6e, 0xf7, 0xed, 0x87, - 0xa3, 0x8d, 0x7f, 0x3e, 0x1c, 0x7d, 0x35, 0xa6, 0x2a, 0x9c, 0xfa, 0xdd, 0x80, 0xc7, 0xd9, 0x3f, - 0xa5, 0xec, 0xcf, 0x99, 0x24, 0x2f, 0x7b, 0xea, 0xf5, 0x04, 0x64, 0x77, 0xc0, 0x94, 0x6b, 0x69, - 0x50, 0x7f, 0xc1, 0xb1, 0x19, 0x6a, 0x46, 0x58, 0x2a, 0xaf, 0x70, 0xa2, 0x04, 0x56, 0xe0, 0x20, - 0xcd, 0xff, 0xe1, 0x23, 0xf8, 0x7d, 0x08, 0xde, 0xbf, 0x39, 0x43, 0xd9, 0x94, 0x7d, 0x08, 0x5c, - 0x3b, 0x21, 0xbb, 0x73, 0xb0, 0x8b, 0x15, 0xd8, 0x80, 0xea, 0xab, 0xaa, 0x7b, 0x6b, 0x50, 0xed, - 0x8a, 0x65, 0x4d, 0x84, 0xf6, 0x62, 0xca, 0x4a, 0x53, 0x35, 0xd7, 0xa0, 0x6a, 0xc4, 0x94, 0xb9, - 0x65, 0x1b, 0x9e, 0x95, 0x6c, 0x0f, 0xd6, 0x62, 0xc3, 0xb3, 0x15, 0xdb, 0x15, 0xda, 0x4f, 0x66, - 0xa3, 0x8c, 0x81, 0x28, 0x39, 0x3f, 0x5b, 0x83, 0xb3, 0x15, 0x53, 0x36, 0x48, 0xe8, 0xb7, 0x88, - 0xf1, 0xec, 0x7f, 0xc4, 0x87, 0x6b, 0x11, 0xe3, 0xd9, 0x6d, 0xe2, 0x6f, 0x91, 0x13, 0xc9, 0xd8, - 0x8b, 0xe8, 0xef, 0x53, 0x4a, 0xb2, 0x77, 0x1a, 0x18, 0xf6, 0x23, 0x20, 0xce, 0xc3, 0x4e, 0xed, - 0xd4, 0x74, 0x1f, 0x44, 0x32, 0xbe, 0xd0, 0x69, 0xfd, 0xb6, 0xfe, 0x9c, 0x26, 0xed, 0x16, 0xda, - 0x0c, 0x71, 0xa4, 0x80, 0x38, 0x7b, 0xba, 0x2c, 0x5b, 0x0d, 0x0d, 0xd3, 0xb0, 0xee, 0x0e, 0x0d, - 0xf3, 0xae, 0xb5, 0x39, 0x34, 0xcc, 0x4d, 0x6b, 0x6b, 0x68, 0x98, 0x5b, 0x96, 0x39, 0x34, 0xcc, - 0x5d, 0xab, 0x3e, 0x34, 0xcc, 0xba, 0x65, 0x0d, 0x0d, 0xd3, 0xb2, 0x1a, 0x4f, 0x2e, 0xde, 0x5e, - 0xb7, 0x6b, 0xef, 0xae, 0xdb, 0xb5, 0x7f, 0xaf, 0xdb, 0xb5, 0x3f, 0x6f, 0xda, 0x1b, 0xef, 0x6e, - 0xda, 0x1b, 0x7f, 0xdf, 0xb4, 0x37, 0x5e, 0x9c, 0x17, 0x46, 0xbc, 0xd4, 0xbf, 0x6e, 0x67, 0x17, - 0xd8, 0x97, 0xbd, 0xec, 0xc3, 0xe2, 0xd5, 0x37, 0xdf, 0xf5, 0x66, 0x8b, 0xcf, 0x0b, 0x3d, 0xb2, - 0xbf, 0xa9, 0x3f, 0x15, 0x1e, 0xfd, 0x17, 0x00, 0x00, 0xff, 0xff, 0x28, 0x4d, 0x6b, 0x6d, 0xb0, - 0x08, 0x00, 0x00, + 0x18, 0xc0, 0xe3, 0xd6, 0x4d, 0x14, 0xa6, 0x89, 0x65, 0xd9, 0xf1, 0x94, 0x74, 0x71, 0x1c, 0xaf, + 0x1b, 0xbc, 0x43, 0x6c, 0x2c, 0x3d, 0x0c, 0x1b, 0x76, 0x58, 0xda, 0x0c, 0xa8, 0x8d, 0xa0, 0x08, + 0x14, 0x60, 0x18, 0x5a, 0x60, 0x02, 0x45, 0x7e, 0xb1, 0xb9, 0x4a, 0xa4, 0x27, 0xd2, 0x8d, 0xbb, + 0xa7, 0xd8, 0x8b, 0xec, 0xd6, 0x87, 0xe8, 0xb1, 0xc8, 0x69, 0xd8, 0xa1, 0x18, 0x92, 0x17, 0x19, + 0x44, 0xfa, 0x8f, 0x6c, 0x65, 0x30, 0x52, 0xf8, 0x64, 0x91, 0xdf, 0xc7, 0xdf, 0xcf, 0x9f, 0xf8, + 0x47, 0x44, 0xfb, 0x52, 0xc5, 0x8c, 0x42, 0x4b, 0x2a, 0xfc, 0x1a, 0x58, 0x40, 0x5a, 0x3d, 0x21, + 0x95, 0xff, 0x87, 0xe0, 0xd0, 0xec, 0xc7, 0x42, 0x09, 0xa7, 0x60, 0x12, 0x9a, 0xe3, 0x84, 0xdd, + 0xcc, 0x88, 0x37, 0x38, 0x64, 0x14, 0x2b, 0x11, 0x9b, 0x11, 0xbb, 0xe5, 0xae, 0xe8, 0x0a, 0xfd, + 0xd8, 0x4a, 0x9e, 0x46, 0xbd, 0x3b, 0x44, 0xc8, 0x48, 0x48, 0xdf, 0x04, 0x4c, 0xc3, 0x84, 0xea, + 0x57, 0x39, 0x54, 0x7a, 0x26, 0xa2, 0x68, 0xc0, 0x99, 0x7a, 0x7b, 0x26, 0x44, 0xe8, 0x41, 0x80, + 0x15, 0x38, 0xaf, 0x50, 0x31, 0xd6, 0x4f, 0x7e, 0x1f, 0x62, 0x02, 0x5c, 0xe1, 0x2e, 0xb8, 0xb9, + 0x5a, 0xae, 0xb1, 0xfe, 0xb4, 0xf9, 0xfe, 0xe3, 0xfe, 0xca, 0x3f, 0x1f, 0xf7, 0xbf, 0xea, 0x32, + 0xd5, 0x1b, 0x04, 0x4d, 0x22, 0xa2, 0x11, 0x73, 0xf4, 0x73, 0x28, 0xe9, 0xeb, 0x96, 0x7a, 0xdb, + 0x07, 0xd9, 0x3c, 0x01, 0xe2, 0xd9, 0x06, 0x74, 0x36, 0xe1, 0x38, 0xbf, 0xa2, 0x52, 0xc8, 0x7e, + 0x1f, 0x30, 0xea, 0xeb, 0x42, 0x7c, 0x1c, 0x89, 0x01, 0x57, 0xee, 0xbd, 0x3b, 0xe3, 0xdb, 0x5c, + 0x79, 0x45, 0x83, 0x3a, 0x4f, 0x48, 0xc7, 0x1a, 0x54, 0xff, 0xcb, 0x46, 0xd6, 0x73, 0x21, 0xd5, + 0x4b, 0xc1, 0xc1, 0xd9, 0x41, 0x16, 0xe9, 0x61, 0xc6, 0x7d, 0x46, 0x4d, 0x01, 0xde, 0x9a, 0x6e, + 0xb7, 0xa9, 0x53, 0x47, 0x0f, 0x03, 0x20, 0xbd, 0x27, 0x47, 0xfd, 0x18, 0x2e, 0xd8, 0xd0, 0x2d, + 0xea, 0xf0, 0x4c, 0x9f, 0xf3, 0x05, 0xda, 0x24, 0x82, 0x73, 0x20, 0x8a, 0x09, 0xcd, 0xb8, 0x67, + 0x92, 0xa6, 0x9d, 0x6d, 0xea, 0x34, 0x51, 0x49, 0xc5, 0x98, 0xcb, 0x0b, 0x88, 0x7d, 0xd2, 0xc3, + 0x9c, 0x43, 0x98, 0xa4, 0x3e, 0xd4, 0xa9, 0xc5, 0x71, 0xe8, 0x99, 0x89, 0xb4, 0xa9, 0xf3, 0x08, + 0xad, 0xb3, 0x80, 0xf8, 0x14, 0xb8, 0x88, 0x5c, 0x4b, 0x67, 0x59, 0x2c, 0x20, 0x27, 0x49, 0xdb, + 0xd9, 0x43, 0x48, 0x2f, 0x04, 0x13, 0x5d, 0xd7, 0xd1, 0xf5, 0xa4, 0xc7, 0x84, 0xbf, 0x46, 0xf6, + 0x80, 0x07, 0x82, 0x53, 0xc6, 0xbb, 0xc9, 0xe4, 0x30, 0x41, 0xdd, 0xdd, 0x5a, 0xae, 0x91, 0xf7, + 0x0a, 0x93, 0xfe, 0x33, 0xdd, 0xed, 0x7c, 0x8f, 0xd0, 0x64, 0x81, 0x48, 0xf7, 0x7e, 0xed, 0x7e, + 0x63, 0xe3, 0x68, 0xb7, 0x39, 0xb7, 0xa8, 0x9a, 0x3f, 0x8f, 0x53, 0xbc, 0x54, 0xb6, 0x73, 0x8c, + 0x0a, 0x14, 0xfa, 0x42, 0x32, 0xe5, 0x63, 0x4a, 0x63, 0x90, 0xd2, 0x75, 0xf4, 0xfc, 0xb8, 0x57, + 0xef, 0x0e, 0xcb, 0xa3, 0x35, 0x74, 0x6c, 0x22, 0xe7, 0x2a, 0x66, 0xbc, 0xeb, 0x6d, 0x8d, 0x06, + 0x8c, 0x7a, 0x9d, 0x17, 0xa8, 0x72, 0xc9, 0x54, 0x8f, 0xc6, 0xf8, 0x12, 0x87, 0x3e, 0x23, 0x78, + 0x42, 0xaa, 0x2c, 0x20, 0x95, 0xa7, 0xe3, 0xda, 0x04, 0x8f, 0x79, 0x3f, 0xa2, 0xc2, 0x05, 0xc0, + 0x0c, 0xe8, 0xb3, 0x05, 0xa0, 0xcd, 0x0b, 0x80, 0x14, 0xe1, 0x05, 0xaa, 0x50, 0x08, 0xa1, 0x8b, + 0xcd, 0x64, 0xa6, 0x40, 0xee, 0xa2, 0x7f, 0x34, 0x1d, 0x37, 0xcb, 0x8b, 0x81, 0x42, 0xd4, 0xcf, + 0xf0, 0x76, 0x16, 0xf1, 0xa6, 0xe3, 0x52, 0x3c, 0x8a, 0xea, 0x64, 0xbc, 0x19, 0xfd, 0xbe, 0x10, + 0xa1, 0x3f, 0x9e, 0x83, 0x34, 0xbb, 0xba, 0x80, 0x5d, 0x25, 0xe9, 0x0d, 0x7d, 0x62, 0x08, 0x29, + 0x4b, 0x80, 0x0e, 0xe6, 0x2c, 0x31, 0xa8, 0x41, 0x3c, 0x5b, 0xc0, 0xfe, 0x02, 0xc9, 0x1e, 0x99, + 0x3d, 0x35, 0x12, 0x40, 0xca, 0xd1, 0x43, 0x8f, 0xe7, 0x1c, 0x66, 0xab, 0xf7, 0x44, 0xa8, 0x17, + 0xee, 0x58, 0x53, 0x5b, 0xa0, 0xa9, 0xcd, 0x68, 0xf4, 0x26, 0x7f, 0x6e, 0x10, 0x63, 0xd3, 0x6f, + 0xe8, 0xcb, 0x4c, 0x35, 0x14, 0x20, 0xca, 0xa8, 0x0e, 0x16, 0xa8, 0x0e, 0xe6, 0x2a, 0x4a, 0x20, + 0x73, 0xae, 0x57, 0xa8, 0xa8, 0x84, 0xc2, 0xc9, 0xb4, 0x8c, 0x57, 0x83, 0x74, 0x37, 0x3f, 0xe9, + 0xd8, 0xb2, 0x35, 0xe8, 0x64, 0xca, 0x71, 0x38, 0x2a, 0x87, 0x58, 0x2a, 0x3f, 0xb5, 0xa2, 0x62, + 0xac, 0xc0, 0x45, 0x9a, 0xff, 0xc3, 0xdd, 0x4e, 0xdd, 0xab, 0x77, 0x87, 0x68, 0x54, 0x65, 0x72, + 0x06, 0x3b, 0x09, 0xd9, 0x9b, 0x80, 0xbd, 0xe4, 0x88, 0x07, 0x54, 0x98, 0x57, 0x6d, 0x2c, 0x41, + 0xb5, 0x15, 0xcf, 0x6a, 0x42, 0x54, 0x8a, 0x18, 0xcf, 0x54, 0x55, 0x5e, 0x82, 0xaa, 0x18, 0x31, + 0xee, 0x65, 0x6d, 0x78, 0x98, 0xb1, 0x6d, 0x2f, 0xc5, 0x86, 0x87, 0x73, 0xb6, 0x4b, 0xb4, 0x93, + 0xd4, 0xc6, 0x38, 0x87, 0x38, 0xe3, 0xfc, 0x7c, 0x09, 0xce, 0x4a, 0xc4, 0x78, 0x3b, 0xa1, 0xdf, + 0x22, 0xc6, 0xc3, 0xff, 0x11, 0xef, 0x2d, 0x45, 0x8c, 0x87, 0xb7, 0x89, 0x7f, 0x41, 0xdb, 0x99, + 0xdd, 0x96, 0x7c, 0xdd, 0xdd, 0x7a, 0x2d, 0xd7, 0xd8, 0x38, 0x7a, 0x9c, 0xf9, 0xba, 0xdc, 0x72, + 0xb9, 0xf0, 0x4a, 0xe4, 0x96, 0x1b, 0xc7, 0xb7, 0xc8, 0x0d, 0x65, 0xe4, 0xcf, 0x5c, 0x0c, 0x80, + 0xe3, 0x20, 0x04, 0xea, 0x3e, 0xaa, 0xe5, 0x1a, 0x96, 0xb7, 0x1d, 0xca, 0xe8, 0x74, 0xfa, 0xb1, + 0xff, 0xc9, 0x04, 0x9d, 0x0a, 0x5a, 0xed, 0xe1, 0x50, 0x01, 0x75, 0x4b, 0x3a, 0x6d, 0xd4, 0xea, + 0xe4, 0xad, 0xbc, 0xfd, 0xa0, 0x93, 0xb7, 0x1e, 0xd8, 0xab, 0x9d, 0xbc, 0xb5, 0x6a, 0xaf, 0x75, + 0xf2, 0xd6, 0x9a, 0x6d, 0x75, 0xf2, 0xd6, 0x96, 0x5d, 0xe8, 0xe4, 0xad, 0x82, 0x6d, 0x77, 0xf2, + 0x96, 0x6d, 0x17, 0x9f, 0x9e, 0xbe, 0xbf, 0xae, 0xe6, 0x3e, 0x5c, 0x57, 0x73, 0xff, 0x5e, 0x57, + 0x73, 0x7f, 0xde, 0x54, 0x57, 0x3e, 0xdc, 0x54, 0x57, 0xfe, 0xbe, 0xa9, 0xae, 0xbc, 0x3c, 0x4a, + 0xbd, 0xbc, 0x73, 0x5d, 0xd9, 0xe1, 0x29, 0x0e, 0x64, 0x6b, 0x74, 0x0f, 0x7b, 0xf3, 0xcd, 0x77, + 0xad, 0xe1, 0xf4, 0x36, 0xa6, 0x5f, 0x66, 0xb0, 0xaa, 0x6f, 0x56, 0x4f, 0xfe, 0x0b, 0x00, 0x00, + 0xff, 0xff, 0xbd, 0xdc, 0x6f, 0x4c, 0xdf, 0x09, 0x00, 0x00, +} + +func (m *CommunityPoolRebate) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CommunityPoolRebate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CommunityPoolRebate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.LiquidStakeAmount.Size() + i -= size + if _, err := m.LiquidStakeAmount.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintHostZone(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size := m.RebatePercentage.Size() + i -= size + if _, err := m.RebatePercentage.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintHostZone(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil } func (m *HostZone) Marshal() (dAtA []byte, err error) { @@ -305,6 +402,20 @@ func (m *HostZone) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.CommunityPoolRebate != nil { + { + size, err := m.CommunityPoolRebate.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintHostZone(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0x92 + } if len(m.CommunityPoolRedeemHoldingAddress) > 0 { i -= len(m.CommunityPoolRedeemHoldingAddress) copy(dAtA[i:], m.CommunityPoolRedeemHoldingAddress) @@ -567,6 +678,19 @@ func encodeVarintHostZone(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } +func (m *CommunityPoolRebate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.RebatePercentage.Size() + n += 1 + l + sovHostZone(uint64(l)) + l = m.LiquidStakeAmount.Size() + n += 1 + l + sovHostZone(uint64(l)) + return n +} + func (m *HostZone) Size() (n int) { if m == nil { return 0 @@ -662,6 +786,10 @@ func (m *HostZone) Size() (n int) { if l > 0 { n += 2 + l + sovHostZone(uint64(l)) } + if m.CommunityPoolRebate != nil { + l = m.CommunityPoolRebate.Size() + n += 2 + l + sovHostZone(uint64(l)) + } return n } @@ -671,6 +799,124 @@ func sovHostZone(x uint64) (n int) { func sozHostZone(x uint64) (n int) { return sovHostZone(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (m *CommunityPoolRebate) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHostZone + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CommunityPoolRebate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CommunityPoolRebate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RebatePercentage", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHostZone + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthHostZone + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthHostZone + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.RebatePercentage.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LiquidStakeAmount", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHostZone + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthHostZone + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthHostZone + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.LiquidStakeAmount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipHostZone(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthHostZone + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *HostZone) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -1511,6 +1757,42 @@ func (m *HostZone) Unmarshal(dAtA []byte) error { } m.CommunityPoolRedeemHoldingAddress = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 34: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CommunityPoolRebate", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHostZone + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthHostZone + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthHostZone + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.CommunityPoolRebate == nil { + m.CommunityPoolRebate = &CommunityPoolRebate{} + } + if err := m.CommunityPoolRebate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipHostZone(dAtA[iNdEx:]) From eb10351578080bf1483c192e6d6b562ca87ca9c2 Mon Sep 17 00:00:00 2001 From: sampocs Date: Fri, 15 Mar 2024 10:49:56 -0500 Subject: [PATCH 03/13] added safely get CP rebate --- x/stakeibc/types/host_zone.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/x/stakeibc/types/host_zone.go b/x/stakeibc/types/host_zone.go index 792855a0a9..e39917b508 100644 --- a/x/stakeibc/types/host_zone.go +++ b/x/stakeibc/types/host_zone.go @@ -23,6 +23,17 @@ func (h HostZone) GetUnbondingFrequency() uint64 { return (h.UnbondingPeriod / MaxUnbondingEntries) + 1 } +// Gets the rebate struct if it exists on the host zone +func (h HostZone) SafelyGetCommunityPoolRebate() (rebate CommunityPoolRebate, exists bool) { + if h.CommunityPoolRebate == nil { + return CommunityPoolRebate{}, false + } + if h.CommunityPoolRebate.LiquidStakeAmount.IsNil() || h.CommunityPoolRebate.RebatePercentage.IsNil() { + return CommunityPoolRebate{}, false + } + return *h.CommunityPoolRebate, true +} + // Generates a new stride-side address on the host zone to escrow deposits func NewHostZoneDepositAddress(chainId string) sdk.AccAddress { key := append([]byte("zone"), []byte(chainId)...) From ffde5708a48bfe6560aa785ec6310181fee6baf0 Mon Sep 17 00:00:00 2001 From: sampocs Date: Fri, 15 Mar 2024 11:04:08 -0500 Subject: [PATCH 04/13] added unit test for safely get CP --- x/stakeibc/types/host_zone_test.go | 60 ++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/x/stakeibc/types/host_zone_test.go b/x/stakeibc/types/host_zone_test.go index 9662cc53d0..aa0debc504 100644 --- a/x/stakeibc/types/host_zone_test.go +++ b/x/stakeibc/types/host_zone_test.go @@ -3,6 +3,8 @@ package types_test import ( "testing" + sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" "github.com/Stride-Labs/stride/v19/x/stakeibc/types" @@ -58,3 +60,61 @@ func TestHostZoneUnbondingFrequency(t *testing.T) { require.Equal(t, tc.unbondingFrequency, hostZone.GetUnbondingFrequency(), "unbonding frequency") } } + +func TestSafelyGetCommunityPoolRebate(t *testing.T) { + chainId := "chain-0" + + testCases := []struct { + name string + hostZone types.HostZone + expectedRebate bool + }{ + { + name: "no rebate", + hostZone: types.HostZone{ChainId: chainId}, + expectedRebate: false, + }, + { + name: "rebate but empty percentage field", + hostZone: types.HostZone{ + ChainId: chainId, + CommunityPoolRebate: &types.CommunityPoolRebate{ + LiquidStakeAmount: sdkmath.NewInt(1), + }, + }, + expectedRebate: false, + }, + { + name: "rebate but empty liquid stake amount", + hostZone: types.HostZone{ + ChainId: chainId, + CommunityPoolRebate: &types.CommunityPoolRebate{ + RebatePercentage: sdk.OneDec(), + }, + }, + expectedRebate: false, + }, + { + name: "valid rebate", + hostZone: types.HostZone{ + ChainId: chainId, + CommunityPoolRebate: &types.CommunityPoolRebate{ + RebatePercentage: sdk.OneDec(), + LiquidStakeAmount: sdkmath.NewInt(1), + }, + }, + expectedRebate: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + actualRebate, hasRebate := tc.hostZone.SafelyGetCommunityPoolRebate() + require.Equal(t, tc.expectedRebate, hasRebate, "has rebate bool") + + if tc.expectedRebate { + require.Equal(t, *tc.hostZone.CommunityPoolRebate, actualRebate, "rebate") + } + }) + } +} From 1e041515113119382741d3baf80dbd7a576d08a0 Mon Sep 17 00:00:00 2001 From: sampocs Date: Tue, 19 Mar 2024 11:19:20 -0500 Subject: [PATCH 05/13] disable trade route ICA swap (#1137) --- x/stakeibc/keeper/hooks.go | 6 ------ x/stakeibc/keeper/reward_converter.go | 2 ++ 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/x/stakeibc/keeper/hooks.go b/x/stakeibc/keeper/hooks.go index 2083723bf2..648214254f 100644 --- a/x/stakeibc/keeper/hooks.go +++ b/x/stakeibc/keeper/hooks.go @@ -89,12 +89,6 @@ func (k Keeper) BeforeEpochStart(ctx sdk.Context, epochInfo epochstypes.EpochInf if epochInfo.Identifier == epochstypes.MINT_EPOCH { k.AllocateHostZoneReward(ctx) } - // At the hour epoch, query the swap price on each trade route and initiate the token swap - if epochInfo.Identifier == epochstypes.HOUR_EPOCH { - k.UpdateAllSwapPrices(ctx) - k.SwapAllRewardTokens(ctx) - } - } func (k Keeper) AfterEpochEnd(ctx sdk.Context, epochInfo epochstypes.EpochInfo) {} diff --git a/x/stakeibc/keeper/reward_converter.go b/x/stakeibc/keeper/reward_converter.go index 9a9fb7d5d5..4730538516 100644 --- a/x/stakeibc/keeper/reward_converter.go +++ b/x/stakeibc/keeper/reward_converter.go @@ -264,6 +264,7 @@ func (k Keeper) BuildSwapMsg(rewardAmount sdkmath.Int, route types.TradeRoute) ( return msg, nil } +// DEPRECATED: The on-chain swap has been deprecated in favor of an authz controller // Trade reward tokens in the Trade ICA for the host denom tokens using ICA remote tx on trade zone // The amount represents the total amount of the reward token in the trade ICA found by the calling ICQ func (k Keeper) SwapRewardTokens(ctx sdk.Context, rewardAmount sdkmath.Int, route types.TradeRoute) error { @@ -461,6 +462,7 @@ func (k Keeper) TradeConvertedBalanceQuery(ctx sdk.Context, route types.TradeRou return nil } +// DEPRECATED: The on-chain swap has been deprecated in favor of an authz controller. Price is no longer needed // Kick off ICQ for the spot price on the pool given the input and output denoms implied by the given TradeRoute // the callback for this query is responsible for updating the returned spot price on the keeper data func (k Keeper) PoolPriceQuery(ctx sdk.Context, route types.TradeRoute) error { From d0b957877f3fb59dac8b3a2a3ed5edacde9ab6ec Mon Sep 17 00:00:00 2001 From: sampocs Date: Tue, 19 Mar 2024 15:47:15 -0500 Subject: [PATCH 06/13] added register rebate tx (#1138) --- proto/stride/stakeibc/tx.proto | 26 + x/stakeibc/client/cli/tx.go | 1 + .../cli/tx_set_community_pool_rebate.go | 61 ++ x/stakeibc/handler.go | 3 + x/stakeibc/keeper/msg_server.go | 28 + x/stakeibc/keeper/msg_server_test.go | 45 ++ x/stakeibc/types/codec.go | 5 +- .../message_set_community_pool_rebate.go | 73 ++ .../message_set_community_pool_rebate_test.go | 162 ++++ x/stakeibc/types/tx.pb.go | 745 +++++++++++++++--- 10 files changed, 1015 insertions(+), 134 deletions(-) create mode 100644 x/stakeibc/client/cli/tx_set_community_pool_rebate.go create mode 100644 x/stakeibc/types/message_set_community_pool_rebate.go create mode 100644 x/stakeibc/types/message_set_community_pool_rebate_test.go diff --git a/proto/stride/stakeibc/tx.proto b/proto/stride/stakeibc/tx.proto index 0aeebbeea9..d6424471b5 100644 --- a/proto/stride/stakeibc/tx.proto +++ b/proto/stride/stakeibc/tx.proto @@ -41,6 +41,8 @@ service Msg { returns (MsgDeleteTradeRouteResponse); rpc UpdateTradeRoute(MsgUpdateTradeRoute) returns (MsgUpdateTradeRouteResponse); + rpc SetCommunityPoolRebate(MsgSetCommunityPoolRebate) + returns (MsgSetCommunityPoolRebateResponse); } message MsgUpdateInnerRedemptionRateBounds { @@ -314,3 +316,27 @@ message MsgUpdateTradeRoute { ]; } message MsgUpdateTradeRouteResponse {} + +// Registers or updates a community pool rebate by specifying the amount liquid +// staked +message MsgSetCommunityPoolRebate { + option (cosmos.msg.v1.signer) = "creator"; + option (amino.name) = "stride/x/stakeibc/MsgSetCommunityPoolRebate"; + + // Message signer (admin only) + string creator = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + // Chain id of the chain whose community pool has a liquid staking rebate + // arrangement with stride + string chain_id = 2; + // Rebate percentage represented as a decimal (e.g. 0.2 for 20%) + string rebate_rate = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // Number of native tokens staked by the community pool + string liquid_staked_amount = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; +} +message MsgSetCommunityPoolRebateResponse {} diff --git a/x/stakeibc/client/cli/tx.go b/x/stakeibc/client/cli/tx.go index 3720db01f7..a2abed08e2 100644 --- a/x/stakeibc/client/cli/tx.go +++ b/x/stakeibc/client/cli/tx.go @@ -40,6 +40,7 @@ func GetTxCmd() *cobra.Command { cmd.AddCommand(CmdClearBalance()) cmd.AddCommand(CmdUpdateInnerRedemptionRateBounds()) cmd.AddCommand(CmdResumeHostZone()) + cmd.AddCommand(CmdSetCommunityPoolRebate()) return cmd } diff --git a/x/stakeibc/client/cli/tx_set_community_pool_rebate.go b/x/stakeibc/client/cli/tx_set_community_pool_rebate.go new file mode 100644 index 0000000000..6fe24f76d4 --- /dev/null +++ b/x/stakeibc/client/cli/tx_set_community_pool_rebate.go @@ -0,0 +1,61 @@ +package cli + +import ( + "errors" + "fmt" + "strings" + + sdkmath "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/spf13/cobra" + + "github.com/Stride-Labs/stride/v19/x/stakeibc/types" +) + +func CmdSetCommunityPoolRebate() *cobra.Command { + cmd := &cobra.Command{ + Use: "set-rebate [chain-id] [rebate-rate] [liquid-staked-amount]", + Short: "Registers or updates a community pool rebate", + Long: strings.TrimSpace(`Registers a community pool rebate by specifying the rebate percentage (as a decimal) +and the amount liquid staked. +E.g. to specify a 20% rebate, the rebate rate should be 0.2 + +If a 0.0 rebate or 0 token liquid stake is specified, the rebate will be deleted. + `), + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) (err error) { + chainId := args[0] + rebatePercentage, err := sdk.NewDecFromStr(args[1]) + if err != nil { + return fmt.Errorf("unable to parse rebate percentage: %s", err.Error()) + } + liquidStakeAmount, ok := sdkmath.NewIntFromString(args[2]) + if !ok { + return errors.New("unable to parse liquid stake amount") + } + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msg := types.NewMsgSetCommunityPoolRebate( + clientCtx.GetFromAddress().String(), + chainId, + rebatePercentage, + liquidStakeAmount, + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/stakeibc/handler.go b/x/stakeibc/handler.go index 9b610df2f0..43f3aefbae 100644 --- a/x/stakeibc/handler.go +++ b/x/stakeibc/handler.go @@ -77,6 +77,9 @@ func NewMessageHandler(k keeper.Keeper) sdk.Handler { case *types.MsgUpdateTradeRoute: res, err := msgServer.UpdateTradeRoute(sdk.WrapSDKContext(ctx), msg) return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgSetCommunityPoolRebate: + res, err := msgServer.SetCommunityPoolRebate(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) default: errMsg := fmt.Sprintf("unrecognized %s message type: %T", types.ModuleName, msg) return nil, errorsmod.Wrap(sdkerrors.ErrUnknownRequest, errMsg) diff --git a/x/stakeibc/keeper/msg_server.go b/x/stakeibc/keeper/msg_server.go index c93982a6a5..0d53345d8a 100644 --- a/x/stakeibc/keeper/msg_server.go +++ b/x/stakeibc/keeper/msg_server.go @@ -1103,3 +1103,31 @@ func (k msgServer) ResumeHostZone(goCtx context.Context, msg *types.MsgResumeHos return &types.MsgResumeHostZoneResponse{}, nil } + +// Registers or updates a community pool rebate, configuring the rebate percentage and liquid stake amount +func (k msgServer) SetCommunityPoolRebate( + goCtx context.Context, + msg *types.MsgSetCommunityPoolRebate, +) (*types.MsgSetCommunityPoolRebateResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + hostZone, found := k.GetHostZone(ctx, msg.ChainId) + if !found { + return nil, types.ErrHostZoneNotFound.Wrapf("host zone %s not found", msg.ChainId) + } + + // If a zero rebate is specified, set the rebate to nil + // Otherwise, update the struct + if msg.LiquidStakedAmount.IsZero() || msg.RebateRate.IsZero() { + hostZone.CommunityPoolRebate = nil + } else { + hostZone.CommunityPoolRebate = &types.CommunityPoolRebate{ + LiquidStakeAmount: msg.LiquidStakedAmount, + RebatePercentage: msg.RebateRate, + } + } + + k.SetHostZone(ctx, hostZone) + + return &types.MsgSetCommunityPoolRebateResponse{}, nil +} diff --git a/x/stakeibc/keeper/msg_server_test.go b/x/stakeibc/keeper/msg_server_test.go index 6a7e280848..26510fe366 100644 --- a/x/stakeibc/keeper/msg_server_test.go +++ b/x/stakeibc/keeper/msg_server_test.go @@ -2575,3 +2575,48 @@ func (s *KeeperTestSuite) TestResumeHostZone_UnhaltedZones() { expectedErrorMsg := fmt.Sprintf("invalid chain id, zone for %s not halted: host zone is not halted", HostChainId) s.Require().Equal(expectedErrorMsg, err.Error(), "should return correct error msg") } + +// ---------------------------------------------------- +// SetCommunityPoolRebate +// ---------------------------------------------------- + +func (s *KeeperTestSuite) TestSetCommunityPoolRebate() { + rebateInfo := types.CommunityPoolRebate{ + LiquidStakeAmount: sdk.NewInt(1000), + RebatePercentage: sdk.MustNewDecFromStr("0.5"), + } + + // Set host zone with no rebate + hostZone := types.HostZone{ + ChainId: HostChainId, + } + s.App.StakeibcKeeper.SetHostZone(s.Ctx, hostZone) + + // Submit a message to create the rebate + msg := types.MsgSetCommunityPoolRebate{ + ChainId: HostChainId, + RebateRate: rebateInfo.RebatePercentage, + LiquidStakedAmount: rebateInfo.LiquidStakeAmount, + } + _, err := s.GetMsgServer().SetCommunityPoolRebate(s.Ctx, &msg) + s.Require().NoError(err, "no error expected when registering rebate") + + // Confirm the rebate was updated + actualHostZone := s.MustGetHostZone(HostChainId) + s.Require().Equal(rebateInfo, *actualHostZone.CommunityPoolRebate, "rebate was updated on host zone") + + // Submit a 0 LS amount which should delete the rebate + removeMsg := types.MsgSetCommunityPoolRebate{ + ChainId: HostChainId, + LiquidStakedAmount: sdk.ZeroInt(), + } + _, err = s.GetMsgServer().SetCommunityPoolRebate(s.Ctx, &removeMsg) + s.Require().NoError(err, "no error expected when registering 0 rebate") + + actualHostZone = s.MustGetHostZone(HostChainId) + s.Require().Nil(actualHostZone.CommunityPoolRebate, "rebate was removed from host zone") + + // Confirm a message with an invalid chain ID would cause an error + _, err = s.GetMsgServer().SetCommunityPoolRebate(s.Ctx, &types.MsgSetCommunityPoolRebate{ChainId: "invalid"}) + s.Require().ErrorContains(err, "host zone not found") +} diff --git a/x/stakeibc/types/codec.go b/x/stakeibc/types/codec.go index df4acc7a9c..3be3ff8c76 100644 --- a/x/stakeibc/types/codec.go +++ b/x/stakeibc/types/codec.go @@ -26,7 +26,7 @@ func RegisterCodec(cdc *codec.LegacyAmino) { cdc.RegisterConcrete(&MsgCalibrateDelegation{}, "stakeibc/CalibrateDelegation", nil) cdc.RegisterConcrete(&MsgUpdateInnerRedemptionRateBounds{}, "stakeibc/UpdateInnerRedemptionRateBounds", nil) cdc.RegisterConcrete(&MsgResumeHostZone{}, "stakeibc/ResumeHostZone", nil) - // this line is used by starport scaffolding # 2 + cdc.RegisterConcrete(&MsgSetCommunityPoolRebate{}, "stakeibc/SetCommunityPoolRebate", nil) } func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { @@ -45,6 +45,7 @@ func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { &MsgCalibrateDelegation{}, &MsgUpdateInnerRedemptionRateBounds{}, &MsgResumeHostZone{}, + &MsgSetCommunityPoolRebate{}, ) registry.RegisterImplementations((*govtypes.Content)(nil), @@ -52,8 +53,6 @@ func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { &ToggleLSMProposal{}, ) - // this line is used by starport scaffolding # 3 - msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) } diff --git a/x/stakeibc/types/message_set_community_pool_rebate.go b/x/stakeibc/types/message_set_community_pool_rebate.go new file mode 100644 index 0000000000..e41b12ca5f --- /dev/null +++ b/x/stakeibc/types/message_set_community_pool_rebate.go @@ -0,0 +1,73 @@ +package types + +import ( + "errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + + errorsmod "cosmossdk.io/errors" + sdkmath "cosmossdk.io/math" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + "github.com/Stride-Labs/stride/v19/utils" +) + +const TypeMsgSetCommunityPoolRebate = "register_community_pool_rebate" + +var _ sdk.Msg = &MsgSetCommunityPoolRebate{} + +func NewMsgSetCommunityPoolRebate( + creator string, + chainId string, + rebateRate sdk.Dec, + liquidStakedAmount sdkmath.Int, +) *MsgSetCommunityPoolRebate { + return &MsgSetCommunityPoolRebate{ + Creator: creator, + ChainId: chainId, + RebateRate: rebateRate, + LiquidStakedAmount: liquidStakedAmount, + } +} + +func (msg *MsgSetCommunityPoolRebate) Route() string { + return RouterKey +} + +func (msg *MsgSetCommunityPoolRebate) Type() string { + return TypeMsgSetCommunityPoolRebate +} + +func (msg *MsgSetCommunityPoolRebate) GetSigners() []sdk.AccAddress { + creator, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{creator} +} + +func (msg *MsgSetCommunityPoolRebate) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgSetCommunityPoolRebate) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + } + if err := utils.ValidateAdminAddress(msg.Creator); err != nil { + return err + } + if msg.ChainId == "" { + return errors.New("chain ID must be specified") + } + if msg.RebateRate.IsNil() || msg.RebateRate.LT(sdk.ZeroDec()) || msg.RebateRate.GT(sdk.OneDec()) { + return errors.New("invalid rebate rate, must be a decimal between 0 and 1 (inclusive)") + } + if msg.LiquidStakedAmount.IsNil() || msg.LiquidStakedAmount.LT(sdkmath.ZeroInt()) { + return errors.New("invalid liquid stake amount, must be greater than or equal to zero") + } + + return nil +} diff --git a/x/stakeibc/types/message_set_community_pool_rebate_test.go b/x/stakeibc/types/message_set_community_pool_rebate_test.go new file mode 100644 index 0000000000..115f847e90 --- /dev/null +++ b/x/stakeibc/types/message_set_community_pool_rebate_test.go @@ -0,0 +1,162 @@ +package types_test + +import ( + "testing" + + sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/stretchr/testify/require" + + "github.com/Stride-Labs/stride/v19/app/apptesting" + "github.com/Stride-Labs/stride/v19/x/stakeibc/types" +) + +func TestMsgSetCommunityPoolRebate(t *testing.T) { + apptesting.SetupConfig() + + validNotAdminAddress, invalidAddress := apptesting.GenerateTestAddrs() + validAdminAddress, ok := apptesting.GetAdminAddress() + require.True(t, ok) + + validChainId := "chain-0" + validRebateRate := sdk.MustNewDecFromStr("0.1") + validLiquidStakedAmount := sdk.NewInt(1000) + + tests := []struct { + name string + msg types.MsgSetCommunityPoolRebate + err string + }{ + { + name: "valid message", + msg: types.MsgSetCommunityPoolRebate{ + Creator: validAdminAddress, + ChainId: validChainId, + RebateRate: validRebateRate, + LiquidStakedAmount: validLiquidStakedAmount, + }, + }, + { + name: "invalid address", + msg: types.MsgSetCommunityPoolRebate{ + Creator: invalidAddress, + ChainId: validChainId, + RebateRate: validRebateRate, + LiquidStakedAmount: validLiquidStakedAmount, + }, + err: "invalid creator address", + }, + { + name: "not admin address", + msg: types.MsgSetCommunityPoolRebate{ + Creator: validNotAdminAddress, + ChainId: validChainId, + RebateRate: validRebateRate, + LiquidStakedAmount: validLiquidStakedAmount, + }, + err: "not an admin", + }, + { + name: "invalid chain ID", + msg: types.MsgSetCommunityPoolRebate{ + Creator: validAdminAddress, + ChainId: "", + RebateRate: validRebateRate, + LiquidStakedAmount: validLiquidStakedAmount, + }, + err: "chain ID must be specified", + }, + { + name: "invalid rebate percentage - nil", + msg: types.MsgSetCommunityPoolRebate{ + Creator: validAdminAddress, + ChainId: validChainId, + LiquidStakedAmount: validLiquidStakedAmount, + }, + err: "rebate percentage, must be between 0 and 1 (inclusive)", + }, + { + name: "invalid rebate percentage - less than 0", + msg: types.MsgSetCommunityPoolRebate{ + Creator: validAdminAddress, + ChainId: validChainId, + RebateRate: sdk.MustNewDecFromStr("0.5").Neg(), + LiquidStakedAmount: validLiquidStakedAmount, + }, + err: "rebate percentage, must be between 0 and 1 (inclusive)", + }, + { + name: "valid rebate percentage - one", + msg: types.MsgSetCommunityPoolRebate{ + Creator: validAdminAddress, + ChainId: validChainId, + RebateRate: sdk.OneDec(), + LiquidStakedAmount: validLiquidStakedAmount, + }, + }, + { + name: "invalid rebate percentage - greater than one", + msg: types.MsgSetCommunityPoolRebate{ + Creator: validAdminAddress, + ChainId: validChainId, + RebateRate: sdk.MustNewDecFromStr("1.1"), + LiquidStakedAmount: validLiquidStakedAmount, + }, + err: "rebate percentage, must be between 0 and 1 (inclusive)", + }, + { + name: "valid zero rebate", + msg: types.MsgSetCommunityPoolRebate{ + Creator: validAdminAddress, + ChainId: validChainId, + RebateRate: sdk.ZeroDec(), + LiquidStakedAmount: validLiquidStakedAmount, + }, + }, + { + name: "invalid liquid stake amount - nil", + msg: types.MsgSetCommunityPoolRebate{ + Creator: validAdminAddress, + ChainId: validChainId, + RebateRate: validRebateRate, + }, + err: "invalid liquid stake amount, must be greater than or equal to 0", + }, + { + name: "invalid liquid stake amount - less than 0", + msg: types.MsgSetCommunityPoolRebate{ + Creator: validAdminAddress, + ChainId: validChainId, + RebateRate: validRebateRate, + LiquidStakedAmount: sdkmath.NewInt(1).Neg(), + }, + err: "invalid liquid stake amount, must be greater than or equal to 0", + }, + { + name: "valid liquid stake amount - zero", + msg: types.MsgSetCommunityPoolRebate{ + Creator: validAdminAddress, + ChainId: validChainId, + RebateRate: validRebateRate, + LiquidStakedAmount: sdkmath.ZeroInt(), + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if test.err == "" { + require.NoError(t, test.msg.ValidateBasic(), "test: %v", test.name) + require.Equal(t, test.msg.Route(), types.RouterKey) + require.Equal(t, test.msg.Type(), "register_community_pool_rebate") + + signers := test.msg.GetSigners() + require.Equal(t, len(signers), 1) + require.Equal(t, signers[0].String(), validAdminAddress) + } else { + require.ErrorContains(t, test.msg.ValidateBasic(), test.err, "test: %v", test.name) + } + }) + } +} diff --git a/x/stakeibc/types/tx.pb.go b/x/stakeibc/types/tx.pb.go index c1327e037f..13b0cca22b 100644 --- a/x/stakeibc/types/tx.pb.go +++ b/x/stakeibc/types/tx.pb.go @@ -1960,6 +1960,103 @@ func (m *MsgUpdateTradeRouteResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgUpdateTradeRouteResponse proto.InternalMessageInfo +// Registers or updates a community pool rebate by specifying the amount liquid +// staked +type MsgSetCommunityPoolRebate struct { + // Message signer (admin only) + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` + // Chain id of the chain whose community pool has a liquid staking rebate + // arrangement with stride + ChainId string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // Rebate percentage represented as a decimal (e.g. 0.2 for 20%) + RebateRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=rebate_rate,json=rebateRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"rebate_rate"` + // Number of native tokens staked by the community pool + LiquidStakedAmount github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,4,opt,name=liquid_staked_amount,json=liquidStakedAmount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"liquid_staked_amount"` +} + +func (m *MsgSetCommunityPoolRebate) Reset() { *m = MsgSetCommunityPoolRebate{} } +func (m *MsgSetCommunityPoolRebate) String() string { return proto.CompactTextString(m) } +func (*MsgSetCommunityPoolRebate) ProtoMessage() {} +func (*MsgSetCommunityPoolRebate) Descriptor() ([]byte, []int) { + return fileDescriptor_9b7e09c9ad51cd54, []int{37} +} +func (m *MsgSetCommunityPoolRebate) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSetCommunityPoolRebate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSetCommunityPoolRebate.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgSetCommunityPoolRebate) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSetCommunityPoolRebate.Merge(m, src) +} +func (m *MsgSetCommunityPoolRebate) XXX_Size() int { + return m.Size() +} +func (m *MsgSetCommunityPoolRebate) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSetCommunityPoolRebate.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSetCommunityPoolRebate proto.InternalMessageInfo + +func (m *MsgSetCommunityPoolRebate) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *MsgSetCommunityPoolRebate) GetChainId() string { + if m != nil { + return m.ChainId + } + return "" +} + +type MsgSetCommunityPoolRebateResponse struct { +} + +func (m *MsgSetCommunityPoolRebateResponse) Reset() { *m = MsgSetCommunityPoolRebateResponse{} } +func (m *MsgSetCommunityPoolRebateResponse) String() string { return proto.CompactTextString(m) } +func (*MsgSetCommunityPoolRebateResponse) ProtoMessage() {} +func (*MsgSetCommunityPoolRebateResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_9b7e09c9ad51cd54, []int{38} +} +func (m *MsgSetCommunityPoolRebateResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSetCommunityPoolRebateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSetCommunityPoolRebateResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgSetCommunityPoolRebateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSetCommunityPoolRebateResponse.Merge(m, src) +} +func (m *MsgSetCommunityPoolRebateResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgSetCommunityPoolRebateResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSetCommunityPoolRebateResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSetCommunityPoolRebateResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*MsgUpdateInnerRedemptionRateBounds)(nil), "stride.stakeibc.MsgUpdateInnerRedemptionRateBounds") proto.RegisterType((*MsgUpdateInnerRedemptionRateBoundsResponse)(nil), "stride.stakeibc.MsgUpdateInnerRedemptionRateBoundsResponse") @@ -1998,142 +2095,150 @@ func init() { proto.RegisterType((*MsgDeleteTradeRouteResponse)(nil), "stride.stakeibc.MsgDeleteTradeRouteResponse") proto.RegisterType((*MsgUpdateTradeRoute)(nil), "stride.stakeibc.MsgUpdateTradeRoute") proto.RegisterType((*MsgUpdateTradeRouteResponse)(nil), "stride.stakeibc.MsgUpdateTradeRouteResponse") + proto.RegisterType((*MsgSetCommunityPoolRebate)(nil), "stride.stakeibc.MsgSetCommunityPoolRebate") + proto.RegisterType((*MsgSetCommunityPoolRebateResponse)(nil), "stride.stakeibc.MsgSetCommunityPoolRebateResponse") } func init() { proto.RegisterFile("stride/stakeibc/tx.proto", fileDescriptor_9b7e09c9ad51cd54) } var fileDescriptor_9b7e09c9ad51cd54 = []byte{ - // 2067 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x59, 0x4f, 0x6f, 0x24, 0x47, - 0x15, 0xf7, 0xac, 0xff, 0x8d, 0x9f, 0xed, 0x1d, 0xbb, 0xed, 0xf5, 0x8e, 0x7b, 0xe3, 0x19, 0x6f, - 0x7b, 0x03, 0xc6, 0x89, 0x67, 0xb0, 0x1d, 0x01, 0x31, 0x20, 0xe1, 0xb1, 0x03, 0x31, 0xac, 0x13, - 0xd4, 0x76, 0xb2, 0xd2, 0x4a, 0x51, 0x53, 0xd3, 0x5d, 0x3b, 0xd3, 0xda, 0xee, 0xae, 0x49, 0x57, - 0x8f, 0x3d, 0xcb, 0x01, 0x45, 0x48, 0x48, 0x08, 0x81, 0x00, 0x71, 0xe5, 0x10, 0x24, 0x0e, 0x08, - 0x2e, 0x11, 0x8a, 0xf8, 0x0c, 0x41, 0x48, 0x28, 0xca, 0x09, 0x71, 0x30, 0x68, 0xf7, 0x10, 0xce, - 0xfe, 0x04, 0xa8, 0xaa, 0xba, 0x6b, 0xba, 0x7b, 0x7a, 0x3c, 0xb6, 0xd7, 0xac, 0xb8, 0xd8, 0xae, - 0xaa, 0x5f, 0xbd, 0xf7, 0x7b, 0xaf, 0x5f, 0xbd, 0x7a, 0xaf, 0x0c, 0x45, 0x1a, 0xf8, 0xb6, 0x85, - 0xab, 0x34, 0x40, 0x8f, 0xb1, 0x5d, 0x37, 0xab, 0x41, 0xa7, 0xd2, 0xf2, 0x49, 0x40, 0x94, 0x82, - 0x58, 0xa9, 0x44, 0x2b, 0x6a, 0x39, 0x0d, 0x3d, 0x46, 0x8e, 0x6d, 0xa1, 0x80, 0xf8, 0x62, 0x87, - 0x3a, 0xdf, 0x20, 0x0d, 0xc2, 0xff, 0xac, 0xb2, 0xbf, 0xc2, 0xd9, 0x45, 0x93, 0x50, 0x97, 0x50, - 0x43, 0x2c, 0x88, 0x41, 0xb8, 0x54, 0x12, 0xa3, 0x6a, 0x1d, 0x51, 0x5c, 0x3d, 0xde, 0xa8, 0xe3, - 0x00, 0x6d, 0x54, 0x4d, 0x62, 0x7b, 0xe1, 0xfa, 0xed, 0x70, 0xdd, 0xa5, 0x8d, 0xea, 0xf1, 0x06, - 0xfb, 0x15, 0x2e, 0xcc, 0x22, 0xd7, 0xf6, 0x48, 0x95, 0xff, 0x14, 0x53, 0xda, 0xdf, 0x6e, 0x80, - 0x76, 0x40, 0x1b, 0xef, 0xb4, 0x2c, 0x14, 0xe0, 0x7d, 0xcf, 0xc3, 0xbe, 0x8e, 0x2d, 0xec, 0xb6, - 0x02, 0x9b, 0x78, 0x3a, 0x0a, 0x70, 0x8d, 0xb4, 0x3d, 0x8b, 0x2a, 0x45, 0x18, 0x37, 0x7d, 0xcc, - 0x48, 0x17, 0x73, 0xcb, 0xb9, 0xd5, 0x09, 0x3d, 0x1a, 0x2a, 0x8b, 0x90, 0x37, 0x9b, 0xc8, 0xf6, - 0x0c, 0xdb, 0x2a, 0xde, 0x08, 0x97, 0xd8, 0x78, 0xdf, 0x52, 0x4e, 0x60, 0xd1, 0x65, 0x0b, 0x4c, - 0xaa, 0xe1, 0x4b, 0xb1, 0x86, 0x8f, 0x02, 0x5c, 0x1c, 0x66, 0xd8, 0xda, 0x37, 0x3e, 0x39, 0x2d, - 0x0f, 0xfd, 0xf3, 0xb4, 0xfc, 0x85, 0x86, 0x1d, 0x34, 0xdb, 0xf5, 0x8a, 0x49, 0xdc, 0xd0, 0xd6, - 0xf0, 0xd7, 0x3a, 0xb5, 0x1e, 0x57, 0x83, 0x27, 0x2d, 0x4c, 0x2b, 0x7b, 0xd8, 0xfc, 0xec, 0xe3, - 0x75, 0x08, 0x5d, 0xb1, 0x87, 0x4d, 0x7d, 0xc1, 0xb5, 0xbd, 0x0c, 0xce, 0x5c, 0x31, 0xea, 0xf4, - 0x51, 0x3c, 0x72, 0x2d, 0x8a, 0x51, 0x27, 0x43, 0xb1, 0xf6, 0x2a, 0xac, 0x0d, 0x76, 0xa6, 0x8e, - 0x69, 0x8b, 0x78, 0x14, 0x6b, 0xbf, 0xce, 0xc1, 0xcd, 0x03, 0xda, 0xb8, 0x6f, 0xbf, 0xdf, 0xb6, - 0xad, 0x43, 0x16, 0x1e, 0xe7, 0xf8, 0xf9, 0xdb, 0x30, 0x86, 0x5c, 0xd2, 0xf6, 0x02, 0xe1, 0xe5, - 0x5a, 0xe5, 0x12, 0x06, 0xec, 0x7b, 0x81, 0x1e, 0xee, 0x56, 0x96, 0x00, 0x9a, 0x84, 0x06, 0x86, - 0x85, 0x3d, 0xe2, 0x8a, 0xaf, 0xa0, 0x4f, 0xb0, 0x99, 0x3d, 0x36, 0xa1, 0x7d, 0x90, 0x83, 0x85, - 0x24, 0xa7, 0x88, 0xae, 0xf2, 0x08, 0xf2, 0x34, 0x30, 0x02, 0xf2, 0x18, 0x7b, 0x9c, 0xdc, 0xe4, - 0xe6, 0x62, 0x25, 0xf4, 0x09, 0x8b, 0xc4, 0x4a, 0x18, 0x89, 0x95, 0x5d, 0x62, 0x7b, 0xb5, 0x2f, - 0x33, 0x7a, 0x7f, 0xfc, 0x57, 0x79, 0xf5, 0x02, 0xf4, 0xd8, 0x06, 0xaa, 0x8f, 0xd3, 0xe0, 0x88, - 0xc9, 0xd6, 0x7e, 0x9f, 0x83, 0x59, 0x46, 0xe1, 0xf0, 0xe0, 0xc5, 0x7a, 0x66, 0x1d, 0xe6, 0x1c, - 0xea, 0x0a, 0x03, 0x0d, 0xbb, 0x6e, 0x26, 0x5c, 0x34, 0xe3, 0x50, 0x97, 0xd3, 0xdb, 0xaf, 0x9b, - 0xc2, 0x53, 0x6f, 0xc1, 0x62, 0x0f, 0x4b, 0xe9, 0xab, 0x0d, 0x98, 0x0f, 0x7c, 0xe4, 0x51, 0x64, - 0xf2, 0xc0, 0x33, 0x89, 0xdb, 0x72, 0x70, 0x80, 0x39, 0xf5, 0xbc, 0x3e, 0x17, 0x5b, 0xdb, 0x0d, - 0x97, 0xb4, 0x3f, 0xe4, 0xa0, 0x70, 0x40, 0x1b, 0xbb, 0x0e, 0x46, 0x7e, 0x0d, 0x39, 0xc8, 0x33, - 0xf1, 0xd5, 0x8e, 0x5d, 0xd7, 0x1f, 0xc3, 0xcf, 0xe5, 0x0f, 0xa6, 0xbc, 0x89, 0x3c, 0x0f, 0x3b, - 0xe2, 0xcc, 0xe8, 0xd1, 0x50, 0x5b, 0x84, 0xdb, 0x29, 0xa6, 0x32, 0xa6, 0xff, 0x24, 0x62, 0x9a, - 0xc5, 0x3d, 0x76, 0x5f, 0xd4, 0x97, 0xbb, 0x03, 0x3c, 0x82, 0x8d, 0x1f, 0x12, 0x2f, 0x4c, 0x2c, - 0x7a, 0x9e, 0x4d, 0x3c, 0x24, 0x1e, 0x56, 0x54, 0xc8, 0xfb, 0xd8, 0xc4, 0xf6, 0x31, 0xf6, 0x43, - 0x3b, 0xe4, 0x58, 0x2b, 0xf2, 0x60, 0x8f, 0x91, 0x95, 0x76, 0xfc, 0x79, 0x14, 0xe6, 0xf8, 0x52, - 0xc3, 0xa6, 0x01, 0xf6, 0xdf, 0x8c, 0xa4, 0x7d, 0x13, 0xa6, 0x4d, 0xe2, 0x79, 0x58, 0x7c, 0xd7, - 0xc8, 0xf9, 0xb5, 0xe2, 0xd9, 0x69, 0x79, 0xfe, 0x09, 0x72, 0x9d, 0x6d, 0x2d, 0xb1, 0xac, 0xe9, - 0x53, 0xdd, 0xf1, 0xbe, 0xa5, 0x68, 0x30, 0x55, 0xc7, 0x66, 0x73, 0x6b, 0xb3, 0xe5, 0xe3, 0x47, - 0x76, 0xa7, 0x38, 0xc5, 0x09, 0x25, 0xe6, 0x94, 0xd7, 0x12, 0x27, 0x54, 0xa4, 0xab, 0x5b, 0x67, - 0xa7, 0xe5, 0x59, 0x21, 0xbf, 0xbb, 0xa6, 0xc5, 0x0e, 0xae, 0xb2, 0x01, 0x13, 0xdd, 0x98, 0x1d, - 0xe5, 0x9b, 0xe6, 0xcf, 0x4e, 0xcb, 0x33, 0x62, 0x93, 0x5c, 0xd2, 0xf4, 0xbc, 0x1d, 0x46, 0x70, - 0xfc, 0xc3, 0x8c, 0x25, 0x3f, 0xcc, 0x5b, 0x20, 0x42, 0xf4, 0x11, 0xf6, 0x8d, 0xf0, 0xa3, 0x33, - 0x5b, 0x81, 0x8b, 0x2d, 0x9d, 0x9d, 0x96, 0x55, 0x21, 0x36, 0x03, 0xa4, 0xe9, 0xb3, 0xd1, 0xec, - 0xae, 0x98, 0xe4, 0x21, 0x39, 0xd3, 0xf6, 0xea, 0xc4, 0xb3, 0x6c, 0xaf, 0x61, 0xb4, 0xb0, 0x6f, - 0x13, 0xab, 0x38, 0xb9, 0x9c, 0x5b, 0x1d, 0xa9, 0xdd, 0x39, 0x3b, 0x2d, 0xdf, 0x16, 0xc2, 0xd2, - 0x08, 0x4d, 0x2f, 0xc8, 0xa9, 0xef, 0xf3, 0x19, 0xc5, 0x81, 0x39, 0x76, 0xa3, 0xa4, 0x53, 0xfa, - 0xf4, 0x35, 0xa4, 0xf4, 0x59, 0xd7, 0xf6, 0x52, 0xd7, 0x08, 0xd3, 0x86, 0x3a, 0x3d, 0xda, 0x6e, - 0x5e, 0x8b, 0x36, 0xd4, 0x49, 0x69, 0xfb, 0x2a, 0x14, 0x59, 0xfa, 0x71, 0x78, 0x36, 0x31, 0x78, - 0xb5, 0x60, 0x60, 0x0f, 0xd5, 0x1d, 0x6c, 0x15, 0x0b, 0x3c, 0x6d, 0xdc, 0x72, 0xa8, 0x1b, 0x4b, - 0x36, 0x6f, 0x88, 0xc5, 0xed, 0xfc, 0x4f, 0x3f, 0x2c, 0x0f, 0xfd, 0xe7, 0xc3, 0xf2, 0x90, 0xb6, - 0x04, 0x77, 0x32, 0x62, 0x56, 0xc6, 0xf4, 0x2f, 0x73, 0x3c, 0x65, 0xed, 0x3a, 0xc8, 0x76, 0xdf, - 0xf1, 0x2c, 0xec, 0xe0, 0x06, 0x0a, 0xb0, 0xc5, 0xd3, 0xda, 0x79, 0x57, 0xfc, 0x32, 0x4c, 0xc9, - 0xe3, 0xd5, 0xcd, 0x37, 0x10, 0x9d, 0xb0, 0x7d, 0x4b, 0x99, 0x87, 0x51, 0xdc, 0x22, 0x66, 0x93, - 0x1f, 0xbe, 0x11, 0x5d, 0x0c, 0x12, 0x27, 0x6f, 0x34, 0x79, 0xf2, 0xbe, 0x3b, 0x92, 0x1f, 0x99, - 0x19, 0xd5, 0x56, 0xe0, 0x6e, 0x5f, 0x42, 0x92, 0x76, 0x10, 0x1e, 0xd2, 0xba, 0x48, 0x35, 0xef, - 0x46, 0xe5, 0xd3, 0x79, 0x94, 0x13, 0x19, 0xe1, 0x46, 0x2a, 0x23, 0xac, 0xc0, 0xb4, 0xd7, 0x76, - 0x0d, 0x3f, 0x92, 0x18, 0xb2, 0x9e, 0xf2, 0xda, 0xae, 0xd4, 0xa2, 0x2d, 0x43, 0x29, 0x5b, 0xab, - 0xe4, 0xf5, 0x93, 0x1c, 0xcc, 0x1c, 0xd0, 0xc6, 0x8e, 0x65, 0x3d, 0x3f, 0xa5, 0x6d, 0x00, 0x59, - 0x16, 0xd2, 0xe2, 0xf0, 0xf2, 0xf0, 0xea, 0xe4, 0xa6, 0x5a, 0x49, 0x95, 0x92, 0x15, 0xa9, 0x47, - 0x8f, 0xa1, 0x35, 0x15, 0x8a, 0x69, 0x1a, 0x92, 0xe3, 0x7b, 0x50, 0x90, 0xb3, 0x0f, 0xb0, 0xdd, - 0x68, 0x06, 0xca, 0x26, 0x8c, 0x23, 0xcb, 0xf2, 0x31, 0xa5, 0x82, 0x61, 0xad, 0xf8, 0xd9, 0xc7, - 0xeb, 0xf3, 0x61, 0x6c, 0xee, 0x88, 0x95, 0xc3, 0xc0, 0xb7, 0xbd, 0x86, 0x1e, 0x01, 0x95, 0x05, - 0x18, 0x3b, 0xe1, 0xbb, 0x39, 0xf1, 0x11, 0x3d, 0x1c, 0x69, 0xbf, 0x0b, 0x23, 0xaa, 0x89, 0xbc, - 0x06, 0x4e, 0x29, 0xba, 0xb2, 0x2f, 0x0e, 0x60, 0x56, 0x5a, 0x67, 0x08, 0x45, 0x91, 0x4b, 0x96, - 0xfb, 0xbb, 0x44, 0x28, 0xd5, 0x67, 0x8e, 0x53, 0x2c, 0xa2, 0x18, 0xcb, 0xa4, 0x28, 0xfd, 0xf4, - 0x41, 0x0e, 0x94, 0x03, 0xda, 0xd8, 0xc3, 0xec, 0x2a, 0x96, 0xa8, 0xab, 0x5a, 0xb0, 0x05, 0xf9, - 0x63, 0xe4, 0x18, 0xcc, 0x7b, 0xe1, 0x1d, 0x7c, 0x8e, 0x8f, 0x8f, 0x91, 0xc3, 0x66, 0xb4, 0x97, - 0x40, 0xed, 0x65, 0x20, 0x09, 0xfe, 0x36, 0x17, 0x9e, 0x6d, 0x1a, 0x10, 0x1f, 0xef, 0x7b, 0x01, - 0xf6, 0xf9, 0x7d, 0xbf, 0x63, 0x9a, 0xf2, 0xb2, 0xbe, 0x74, 0xa5, 0xb0, 0x92, 0xbe, 0xcc, 0xc4, - 0xdd, 0x99, 0xbc, 0xb2, 0x56, 0x60, 0x1a, 0x09, 0x25, 0x06, 0x39, 0xf1, 0xe4, 0x25, 0x3a, 0x15, - 0x4e, 0xbe, 0xcd, 0xe6, 0xb4, 0x97, 0x61, 0xe5, 0x1c, 0x76, 0xd2, 0x8a, 0xf7, 0x61, 0x59, 0xd6, - 0xc7, 0xd2, 0xc6, 0xc3, 0x26, 0xf2, 0x31, 0x7d, 0xa3, 0x63, 0x36, 0x79, 0x1e, 0xbc, 0x92, 0x25, - 0x45, 0x60, 0x7e, 0x24, 0x2d, 0x1c, 0x3a, 0x5c, 0x8f, 0x86, 0xda, 0x1a, 0xac, 0x0e, 0x52, 0x29, - 0xe9, 0x35, 0x78, 0xa6, 0xd9, 0x45, 0x8e, 0x5d, 0x67, 0x99, 0x7e, 0x4f, 0x24, 0x24, 0x9b, 0x78, - 0xd7, 0x4d, 0x4a, 0x24, 0x97, 0x0c, 0x45, 0x92, 0xca, 0x9b, 0xbc, 0x06, 0xd6, 0x31, 0x6d, 0xbb, - 0x58, 0x16, 0x1f, 0x57, 0x61, 0xa1, 0xdd, 0xe1, 0x47, 0x34, 0x29, 0x49, 0xaa, 0xf9, 0x79, 0x9e, - 0x97, 0x39, 0xbb, 0x4c, 0x0c, 0x3e, 0xf2, 0x91, 0x85, 0x75, 0xd2, 0x0e, 0xb0, 0xf2, 0x15, 0x98, - 0x40, 0xed, 0xa0, 0x49, 0x7c, 0x3b, 0x78, 0x32, 0x30, 0x4d, 0x74, 0xa1, 0x8a, 0x06, 0xd3, 0xfc, - 0x58, 0xa4, 0xc8, 0x4c, 0xb2, 0xc9, 0xdd, 0xd0, 0x2d, 0x35, 0x28, 0x89, 0x53, 0x6c, 0x04, 0xc4, - 0xf0, 0xf1, 0x09, 0xf2, 0x2d, 0x23, 0x2b, 0x0c, 0x55, 0x81, 0x3a, 0x22, 0x3a, 0xc7, 0xec, 0xc6, - 0x83, 0xf2, 0x5b, 0xb0, 0xd4, 0x95, 0x11, 0x30, 0xde, 0x29, 0x11, 0x22, 0x48, 0x17, 0x23, 0x11, - 0xdc, 0xb4, 0x84, 0x84, 0x7d, 0x10, 0x95, 0x54, 0x97, 0x43, 0x56, 0xc5, 0x23, 0xae, 0xad, 0x25, - 0x86, 0x8c, 0x78, 0x1c, 0xf5, 0x54, 0x37, 0xdf, 0x83, 0x95, 0x48, 0x44, 0x44, 0x26, 0x4b, 0x96, - 0xa8, 0xb1, 0x4a, 0x02, 0x1a, 0x52, 0xea, 0x15, 0xf6, 0x1d, 0xb8, 0x1b, 0x8a, 0x20, 0x86, 0x20, - 0x98, 0x21, 0x6a, 0x9c, 0x8b, 0x7a, 0x89, 0x03, 0x8f, 0x08, 0xfb, 0xaa, 0xbd, 0x82, 0xaa, 0x30, - 0x1f, 0xb2, 0xe2, 0x85, 0x9f, 0x41, 0x3c, 0x2e, 0xaf, 0x98, 0xe7, 0x7b, 0x67, 0xc5, 0x1a, 0x2f, - 0x04, 0xdf, 0xf6, 0x98, 0x04, 0x65, 0x0b, 0x16, 0xd2, 0x1b, 0xc4, 0xb8, 0x38, 0xc1, 0xb7, 0xcc, - 0x25, 0xb6, 0x08, 0x67, 0x28, 0x1b, 0x70, 0x2b, 0xbd, 0x89, 0xb3, 0x12, 0xb5, 0xa2, 0xae, 0x24, - 0xf6, 0x70, 0x93, 0x59, 0x9f, 0xd5, 0xad, 0x61, 0xbb, 0x1b, 0x26, 0x45, 0x9f, 0x25, 0x2b, 0xda, - 0x08, 0xfe, 0x0a, 0x28, 0x49, 0x38, 0xb7, 0x42, 0x14, 0xce, 0x85, 0x18, 0x9a, 0xdb, 0x70, 0x1b, - 0xc6, 0x5b, 0x84, 0x70, 0x1f, 0x4d, 0x8b, 0x9b, 0x8a, 0x0d, 0xf7, 0x2d, 0x65, 0x1b, 0x54, 0x56, - 0xcb, 0x21, 0xc7, 0x21, 0x27, 0xd8, 0x32, 0xe8, 0x09, 0x6a, 0x19, 0x0e, 0xa1, 0x34, 0x56, 0xd2, - 0xf1, 0xae, 0x7e, 0x47, 0x00, 0x0e, 0x4f, 0x50, 0xeb, 0x3e, 0xa1, 0x94, 0x67, 0xa4, 0x77, 0xa1, - 0xc0, 0xaa, 0x4e, 0xbe, 0x27, 0xec, 0x57, 0x0a, 0x57, 0xea, 0x57, 0xa6, 0x5d, 0xdb, 0x63, 0x92, - 0x77, 0x44, 0xdb, 0xc2, 0xe4, 0xa2, 0x4e, 0x42, 0xee, 0xcc, 0x15, 0xe5, 0xa2, 0x4e, 0x57, 0xee, - 0xf6, 0xd7, 0x7e, 0xfc, 0xf9, 0x47, 0x6b, 0xdd, 0x43, 0xf9, 0xb3, 0xcf, 0x3f, 0x5a, 0x7b, 0x39, - 0x7c, 0x84, 0xea, 0x74, 0x9f, 0xa1, 0x32, 0x8e, 0x7d, 0x58, 0x40, 0xa6, 0xa7, 0x65, 0xb6, 0xf8, - 0x6b, 0x8e, 0x67, 0x0b, 0x71, 0x47, 0x5d, 0x43, 0xb6, 0xb8, 0x0b, 0x53, 0xf1, 0xe0, 0x89, 0x92, - 0x45, 0x2c, 0x66, 0x06, 0x3c, 0x57, 0x5c, 0xdc, 0xd4, 0x34, 0xe7, 0xd0, 0xd4, 0xf4, 0xb4, 0x34, - 0xf5, 0xef, 0xc3, 0xdc, 0x54, 0x71, 0x6f, 0xfc, 0x3f, 0x98, 0x1a, 0x0f, 0xed, 0x91, 0x4b, 0x84, - 0xf6, 0xe8, 0x65, 0x43, 0x7b, 0xec, 0x7f, 0x14, 0xda, 0xe3, 0x2f, 0x34, 0xb4, 0xd3, 0x1f, 0x2e, - 0xfc, 0xde, 0xe9, 0xe9, 0xe8, 0x7b, 0x6f, 0xfe, 0xa5, 0x00, 0xc3, 0x07, 0xb4, 0xa1, 0x3c, 0x80, - 0xc9, 0xf8, 0xab, 0x53, 0xb9, 0xa7, 0xe0, 0x4c, 0x3e, 0x8e, 0xa9, 0x5f, 0x1c, 0x00, 0x90, 0x2f, - 0x42, 0x3f, 0x80, 0x9b, 0xa9, 0x17, 0x2d, 0x2d, 0x73, 0x6b, 0x02, 0xa3, 0xae, 0x0d, 0xc6, 0x48, - 0x0d, 0x0f, 0x60, 0x32, 0xfe, 0xec, 0x92, 0x49, 0x3d, 0x06, 0xc8, 0xa6, 0x9e, 0xf1, 0x16, 0xa2, - 0x3c, 0x82, 0x99, 0x9e, 0x77, 0x90, 0x7b, 0xd9, 0x9b, 0x93, 0x28, 0xf5, 0xd5, 0x8b, 0xa0, 0xa4, - 0x9e, 0x0e, 0x2c, 0xf4, 0xe9, 0x4d, 0x33, 0xdd, 0x90, 0x8d, 0x55, 0x37, 0x2f, 0x8e, 0x95, 0x9a, - 0x09, 0xcc, 0x65, 0xf5, 0x97, 0x7d, 0x3c, 0xd4, 0x03, 0x54, 0xab, 0x17, 0x04, 0x4a, 0x85, 0xef, - 0xc1, 0x74, 0xb2, 0x6f, 0xbc, 0x9b, 0x25, 0x21, 0x01, 0x51, 0xbf, 0x34, 0x10, 0x22, 0xc5, 0x9f, - 0xc0, 0xad, 0xcc, 0x86, 0xa7, 0x8f, 0x23, 0x33, 0x7b, 0xa3, 0x3e, 0x8e, 0x3c, 0xb7, 0x8f, 0x52, - 0x4c, 0x28, 0xa4, 0x7b, 0xa8, 0x95, 0x2c, 0x31, 0x29, 0x90, 0xfa, 0xca, 0x05, 0x40, 0x52, 0xc9, - 0x8f, 0xa0, 0xd8, 0xb7, 0x0f, 0xea, 0x13, 0x71, 0xd9, 0x68, 0xf5, 0xb5, 0xcb, 0xa0, 0xa5, 0xfe, - 0x5f, 0xe4, 0x60, 0xe9, 0xfc, 0x1e, 0x66, 0x23, 0x4b, 0xee, 0xb9, 0x5b, 0xd4, 0xd7, 0x2f, 0xbd, - 0x25, 0x1e, 0xbd, 0x59, 0x3d, 0x4b, 0x66, 0xf4, 0x66, 0x00, 0xb3, 0xa3, 0xf7, 0x9c, 0xe6, 0x44, - 0x79, 0x08, 0x53, 0x89, 0x67, 0xea, 0xe5, 0xec, 0x23, 0xd7, 0x45, 0xa8, 0xab, 0x83, 0x10, 0x52, - 0xf6, 0x6f, 0x72, 0x50, 0x1e, 0xf4, 0xdf, 0xa8, 0xad, 0xfe, 0xbe, 0xea, 0xbb, 0x49, 0xfd, 0xfa, - 0x15, 0x36, 0xc5, 0xb3, 0x77, 0xaa, 0x17, 0xd3, 0xfa, 0x84, 0x4e, 0x0c, 0x93, 0x9d, 0xbd, 0xb3, - 0x3b, 0x31, 0x96, 0x64, 0x7b, 0xba, 0xb0, 0xcc, 0x24, 0x9b, 0x46, 0x65, 0x27, 0xd9, 0x7e, 0x35, - 0x1c, 0xd3, 0xd3, 0x53, 0xbf, 0xdd, 0xeb, 0x7f, 0xfa, 0x06, 0xe9, 0xe9, 0x57, 0x40, 0x31, 0x3d, - 0x3d, 0xc5, 0xd3, 0xbd, 0xfe, 0x9f, 0x60, 0x90, 0x9e, 0x7e, 0x17, 0x77, 0xed, 0xfe, 0x27, 0x4f, - 0x4b, 0xb9, 0x4f, 0x9f, 0x96, 0x72, 0xff, 0x7e, 0x5a, 0xca, 0xfd, 0xea, 0x59, 0x69, 0xe8, 0xd3, - 0x67, 0xa5, 0xa1, 0x7f, 0x3c, 0x2b, 0x0d, 0x3d, 0xdc, 0x8c, 0x95, 0x18, 0x87, 0x5c, 0xe2, 0xfa, - 0x7d, 0x54, 0xa7, 0xd5, 0xb0, 0x5e, 0x38, 0xde, 0x78, 0x3d, 0x5e, 0x33, 0xf0, 0x92, 0xa3, 0x3e, - 0xc6, 0xff, 0x2b, 0xba, 0xf5, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xbf, 0xc0, 0x2b, 0x90, 0xe0, - 0x1d, 0x00, 0x00, + // 2172 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x59, 0xd1, 0x6f, 0x1c, 0x47, + 0x19, 0xf7, 0xc5, 0x76, 0x7c, 0xf9, 0x6c, 0xc7, 0xf6, 0xda, 0x49, 0xce, 0x9b, 0xe6, 0xce, 0x59, + 0xa7, 0x60, 0x9c, 0xfa, 0x0e, 0xdb, 0x15, 0x50, 0x53, 0x24, 0x7c, 0xe7, 0x42, 0x0d, 0x71, 0x53, + 0xad, 0xdd, 0x46, 0x8a, 0x54, 0x6d, 0xe7, 0x76, 0x27, 0x77, 0xab, 0xec, 0xee, 0x5c, 0x77, 0xf7, + 0xec, 0x0b, 0x0f, 0xa8, 0x42, 0x42, 0x42, 0x08, 0x04, 0x88, 0x57, 0x1e, 0x8a, 0xc4, 0x03, 0x82, + 0x97, 0x08, 0xf5, 0x8f, 0x28, 0x42, 0x42, 0x55, 0x9f, 0x10, 0x48, 0x06, 0x25, 0x0f, 0xe5, 0xd9, + 0x7f, 0x01, 0x9a, 0x99, 0xdd, 0xb9, 0xdd, 0xbd, 0xb9, 0x3b, 0xdb, 0x35, 0x51, 0x5f, 0x12, 0xef, + 0xcc, 0x37, 0xdf, 0xf7, 0xfb, 0xbe, 0xf9, 0xe6, 0x9b, 0xdf, 0x37, 0x07, 0x85, 0x20, 0xf4, 0x6d, + 0x0b, 0x57, 0x82, 0x10, 0x3d, 0xc6, 0x76, 0xdd, 0xac, 0x84, 0x9d, 0x72, 0xcb, 0x27, 0x21, 0x51, + 0x66, 0xf8, 0x4c, 0x39, 0x9e, 0x51, 0x4b, 0x59, 0xd1, 0x43, 0xe4, 0xd8, 0x16, 0x0a, 0x89, 0xcf, + 0x57, 0xa8, 0x0b, 0x0d, 0xd2, 0x20, 0xec, 0xcf, 0x0a, 0xfd, 0x2b, 0x1a, 0x5d, 0x34, 0x49, 0xe0, + 0x92, 0xc0, 0xe0, 0x13, 0xfc, 0x23, 0x9a, 0x2a, 0xf2, 0xaf, 0x4a, 0x1d, 0x05, 0xb8, 0x72, 0xb8, + 0x5e, 0xc7, 0x21, 0x5a, 0xaf, 0x98, 0xc4, 0xf6, 0xa2, 0xf9, 0x1b, 0xd1, 0xbc, 0x1b, 0x34, 0x2a, + 0x87, 0xeb, 0xf4, 0xbf, 0x68, 0x62, 0x0e, 0xb9, 0xb6, 0x47, 0x2a, 0xec, 0x5f, 0x3e, 0xa4, 0xfd, + 0xed, 0x12, 0x68, 0x7b, 0x41, 0xe3, 0x9d, 0x96, 0x85, 0x42, 0xbc, 0xeb, 0x79, 0xd8, 0xd7, 0xb1, + 0x85, 0xdd, 0x56, 0x68, 0x13, 0x4f, 0x47, 0x21, 0xae, 0x92, 0xb6, 0x67, 0x05, 0x4a, 0x01, 0x26, + 0x4c, 0x1f, 0x53, 0xd0, 0x85, 0xdc, 0x52, 0x6e, 0xe5, 0x8a, 0x1e, 0x7f, 0x2a, 0x8b, 0x90, 0x37, + 0x9b, 0xc8, 0xf6, 0x0c, 0xdb, 0x2a, 0x5c, 0x8a, 0xa6, 0xe8, 0xf7, 0xae, 0xa5, 0x1c, 0xc1, 0xa2, + 0x4b, 0x27, 0xa8, 0x56, 0xc3, 0x17, 0x6a, 0x0d, 0x1f, 0x85, 0xb8, 0x30, 0x4a, 0x65, 0xab, 0xaf, + 0x7f, 0x72, 0x5c, 0x1a, 0xf9, 0xe7, 0x71, 0xe9, 0x2b, 0x0d, 0x3b, 0x6c, 0xb6, 0xeb, 0x65, 0x93, + 0xb8, 0x91, 0xaf, 0xd1, 0x7f, 0x6b, 0x81, 0xf5, 0xb8, 0x12, 0x3e, 0x69, 0xe1, 0xa0, 0xbc, 0x83, + 0xcd, 0xcf, 0x3e, 0x5e, 0x83, 0x28, 0x14, 0x3b, 0xd8, 0xd4, 0xaf, 0xbb, 0xb6, 0x27, 0xc1, 0xcc, + 0x0c, 0xa3, 0x4e, 0x1f, 0xc3, 0x63, 0x17, 0x62, 0x18, 0x75, 0x24, 0x86, 0xb5, 0x57, 0x60, 0x75, + 0x78, 0x30, 0x75, 0x1c, 0xb4, 0x88, 0x17, 0x60, 0xed, 0x37, 0x39, 0xb8, 0xba, 0x17, 0x34, 0xee, + 0xd9, 0x1f, 0xb4, 0x6d, 0x6b, 0x9f, 0xa6, 0xc7, 0x80, 0x38, 0x7f, 0x0f, 0x2e, 0x23, 0x97, 0xb4, + 0xbd, 0x90, 0x47, 0xb9, 0x5a, 0x3e, 0x83, 0x03, 0xbb, 0x5e, 0xa8, 0x47, 0xab, 0x95, 0x5b, 0x00, + 0x4d, 0x12, 0x84, 0x86, 0x85, 0x3d, 0xe2, 0xf2, 0x5d, 0xd0, 0xaf, 0xd0, 0x91, 0x1d, 0x3a, 0xa0, + 0x7d, 0x98, 0x83, 0xeb, 0x69, 0x4c, 0x31, 0x5c, 0xe5, 0x11, 0xe4, 0x83, 0xd0, 0x08, 0xc9, 0x63, + 0xec, 0x31, 0x70, 0x93, 0x1b, 0x8b, 0xe5, 0x28, 0x26, 0x34, 0x13, 0xcb, 0x51, 0x26, 0x96, 0x6b, + 0xc4, 0xf6, 0xaa, 0x5f, 0xa7, 0xf0, 0xfe, 0xf4, 0xef, 0xd2, 0xca, 0x29, 0xe0, 0xd1, 0x05, 0x81, + 0x3e, 0x11, 0x84, 0x07, 0x54, 0xb7, 0xf6, 0x87, 0x1c, 0xcc, 0x51, 0x08, 0xfb, 0x7b, 0x2f, 0x36, + 0x32, 0x6b, 0x30, 0xef, 0x04, 0x2e, 0x77, 0xd0, 0xb0, 0xeb, 0x66, 0x2a, 0x44, 0xb3, 0x4e, 0xe0, + 0x32, 0x78, 0xbb, 0x75, 0x93, 0x47, 0xea, 0x2d, 0x58, 0xec, 0x41, 0x29, 0x62, 0xb5, 0x0e, 0x0b, + 0xa1, 0x8f, 0xbc, 0x00, 0x99, 0x2c, 0xf1, 0x4c, 0xe2, 0xb6, 0x1c, 0x1c, 0x62, 0x06, 0x3d, 0xaf, + 0xcf, 0x27, 0xe6, 0x6a, 0xd1, 0x94, 0xf6, 0xc7, 0x1c, 0xcc, 0xec, 0x05, 0x8d, 0x9a, 0x83, 0x91, + 0x5f, 0x45, 0x0e, 0xf2, 0x4c, 0x7c, 0xbe, 0x63, 0xd7, 0x8d, 0xc7, 0xe8, 0x17, 0x8a, 0x07, 0x35, + 0xde, 0x44, 0x9e, 0x87, 0x1d, 0x7e, 0x66, 0xf4, 0xf8, 0x53, 0x5b, 0x84, 0x1b, 0x19, 0xa4, 0x22, + 0xa7, 0xff, 0xcc, 0x73, 0x9a, 0xe6, 0x3d, 0x76, 0x5f, 0xd4, 0xce, 0xdd, 0x04, 0x96, 0xc1, 0xc6, + 0x8f, 0x88, 0x17, 0x15, 0x16, 0x3d, 0x4f, 0x07, 0x1e, 0x12, 0x0f, 0x2b, 0x2a, 0xe4, 0x7d, 0x6c, + 0x62, 0xfb, 0x10, 0xfb, 0x91, 0x1f, 0xe2, 0x5b, 0x2b, 0xb0, 0x64, 0x4f, 0x80, 0x15, 0x7e, 0xfc, + 0x65, 0x1c, 0xe6, 0xd9, 0x54, 0xc3, 0x0e, 0x42, 0xec, 0xbf, 0x19, 0x6b, 0xfb, 0x0e, 0x4c, 0x9b, + 0xc4, 0xf3, 0x30, 0xdf, 0xd7, 0x38, 0xf8, 0xd5, 0xc2, 0xc9, 0x71, 0x69, 0xe1, 0x09, 0x72, 0x9d, + 0x2d, 0x2d, 0x35, 0xad, 0xe9, 0x53, 0xdd, 0xef, 0x5d, 0x4b, 0xd1, 0x60, 0xaa, 0x8e, 0xcd, 0xe6, + 0xe6, 0x46, 0xcb, 0xc7, 0x8f, 0xec, 0x4e, 0x61, 0x8a, 0x01, 0x4a, 0x8d, 0x29, 0xaf, 0xa6, 0x4e, + 0x28, 0x2f, 0x57, 0xd7, 0x4e, 0x8e, 0x4b, 0x73, 0x5c, 0x7f, 0x77, 0x4e, 0x4b, 0x1c, 0x5c, 0x65, + 0x1d, 0xae, 0x74, 0x73, 0x76, 0x9c, 0x2d, 0x5a, 0x38, 0x39, 0x2e, 0xcd, 0xf2, 0x45, 0x62, 0x4a, + 0xd3, 0xf3, 0x76, 0x94, 0xc1, 0xc9, 0x8d, 0xb9, 0x9c, 0xde, 0x98, 0xb7, 0x80, 0xa7, 0xe8, 0x23, + 0xec, 0x1b, 0xd1, 0xa6, 0x53, 0x5f, 0x81, 0xa9, 0x2d, 0x9e, 0x1c, 0x97, 0x54, 0xae, 0x56, 0x22, + 0xa4, 0xe9, 0x73, 0xf1, 0x68, 0x8d, 0x0f, 0xb2, 0x94, 0x9c, 0x6d, 0x7b, 0x75, 0xe2, 0x59, 0xb6, + 0xd7, 0x30, 0x5a, 0xd8, 0xb7, 0x89, 0x55, 0x98, 0x5c, 0xca, 0xad, 0x8c, 0x55, 0x6f, 0x9e, 0x1c, + 0x97, 0x6e, 0x70, 0x65, 0x59, 0x09, 0x4d, 0x9f, 0x11, 0x43, 0x6f, 0xb3, 0x11, 0xc5, 0x81, 0x79, + 0x7a, 0xa3, 0x64, 0x4b, 0xfa, 0xf4, 0x05, 0x94, 0xf4, 0x39, 0xd7, 0xf6, 0x32, 0xd7, 0x08, 0xb5, + 0x86, 0x3a, 0x3d, 0xd6, 0xae, 0x5e, 0x88, 0x35, 0xd4, 0xc9, 0x58, 0xfb, 0x26, 0x14, 0x68, 0xf9, + 0x71, 0x58, 0x35, 0x31, 0x18, 0x5b, 0x30, 0xb0, 0x87, 0xea, 0x0e, 0xb6, 0x0a, 0x33, 0xac, 0x6c, + 0x5c, 0x73, 0x02, 0x37, 0x51, 0x6c, 0xde, 0xe0, 0x93, 0x5b, 0xf9, 0x9f, 0x7d, 0x54, 0x1a, 0xf9, + 0xef, 0x47, 0xa5, 0x11, 0xed, 0x16, 0xdc, 0x94, 0xe4, 0xac, 0xc8, 0xe9, 0x5f, 0xe5, 0x58, 0xc9, + 0xaa, 0x39, 0xc8, 0x76, 0xdf, 0xf1, 0x2c, 0xec, 0xe0, 0x06, 0x0a, 0xb1, 0xc5, 0xca, 0xda, 0xa0, + 0x2b, 0x7e, 0x09, 0xa6, 0xc4, 0xf1, 0xea, 0xd6, 0x1b, 0x88, 0x4f, 0xd8, 0xae, 0xa5, 0x2c, 0xc0, + 0x38, 0x6e, 0x11, 0xb3, 0xc9, 0x0e, 0xdf, 0x98, 0xce, 0x3f, 0x52, 0x27, 0x6f, 0x3c, 0x7d, 0xf2, + 0x7e, 0x30, 0x96, 0x1f, 0x9b, 0x1d, 0xd7, 0x96, 0xe1, 0x76, 0x5f, 0x40, 0x02, 0x76, 0x18, 0x1d, + 0xd2, 0x3a, 0x2f, 0x35, 0xef, 0xc6, 0xf4, 0x69, 0x10, 0xe4, 0x54, 0x45, 0xb8, 0x94, 0xa9, 0x08, + 0xcb, 0x30, 0xed, 0xb5, 0x5d, 0xc3, 0x8f, 0x35, 0x46, 0xa8, 0xa7, 0xbc, 0xb6, 0x2b, 0xac, 0x68, + 0x4b, 0x50, 0x94, 0x5b, 0x15, 0xb8, 0x7e, 0x9a, 0x83, 0xd9, 0xbd, 0xa0, 0xb1, 0x6d, 0x59, 0x5f, + 0x1c, 0xd2, 0x16, 0x80, 0xa0, 0x85, 0x41, 0x61, 0x74, 0x69, 0x74, 0x65, 0x72, 0x43, 0x2d, 0x67, + 0xa8, 0x64, 0x59, 0xd8, 0xd1, 0x13, 0xd2, 0x9a, 0x0a, 0x85, 0x2c, 0x0c, 0x81, 0xf1, 0x3d, 0x98, + 0x11, 0xa3, 0x0f, 0xb0, 0xdd, 0x68, 0x86, 0xca, 0x06, 0x4c, 0x20, 0xcb, 0xf2, 0x71, 0x10, 0x70, + 0x84, 0xd5, 0xc2, 0x67, 0x1f, 0xaf, 0x2d, 0x44, 0xb9, 0xb9, 0xcd, 0x67, 0xf6, 0x43, 0xdf, 0xf6, + 0x1a, 0x7a, 0x2c, 0xa8, 0x5c, 0x87, 0xcb, 0x47, 0x6c, 0x35, 0x03, 0x3e, 0xa6, 0x47, 0x5f, 0xda, + 0xef, 0xa3, 0x8c, 0x6a, 0x22, 0xaf, 0x81, 0x33, 0x86, 0xce, 0x1d, 0x8b, 0x3d, 0x98, 0x13, 0xde, + 0x19, 0xdc, 0x50, 0x1c, 0x92, 0xa5, 0xfe, 0x21, 0xe1, 0x46, 0xf5, 0xd9, 0xc3, 0x0c, 0x8a, 0x38, + 0xc7, 0xa4, 0x10, 0x45, 0x9c, 0x3e, 0xcc, 0x81, 0xb2, 0x17, 0x34, 0x76, 0x30, 0xbd, 0x8a, 0x85, + 0xd4, 0x79, 0x3d, 0xd8, 0x84, 0xfc, 0x21, 0x72, 0x0c, 0x1a, 0xbd, 0xe8, 0x0e, 0x1e, 0x10, 0xe3, + 0x43, 0xe4, 0xd0, 0x11, 0xed, 0x25, 0x50, 0x7b, 0x11, 0x08, 0x80, 0xbf, 0xcb, 0x45, 0x67, 0x3b, + 0x08, 0x89, 0x8f, 0x77, 0xbd, 0x10, 0xfb, 0xec, 0xbe, 0xdf, 0x36, 0x4d, 0x71, 0x59, 0x9f, 0x99, + 0x29, 0x2c, 0x67, 0x2f, 0x33, 0x7e, 0x77, 0xa6, 0xaf, 0xac, 0x65, 0x98, 0x46, 0xdc, 0x88, 0x41, + 0x8e, 0x3c, 0x71, 0x89, 0x4e, 0x45, 0x83, 0xf7, 0xe9, 0x98, 0xf6, 0x32, 0x2c, 0x0f, 0x40, 0x27, + 0xbc, 0xf8, 0x00, 0x96, 0x04, 0x3f, 0x16, 0x3e, 0xee, 0x37, 0x91, 0x8f, 0x83, 0x37, 0x3a, 0x66, + 0x93, 0xd5, 0xc1, 0x73, 0x79, 0x52, 0x00, 0x1a, 0x47, 0xd2, 0xc2, 0x51, 0xc0, 0xf5, 0xf8, 0x53, + 0x5b, 0x85, 0x95, 0x61, 0x26, 0x05, 0xbc, 0x06, 0xab, 0x34, 0x35, 0xe4, 0xd8, 0x75, 0x5a, 0xe9, + 0x77, 0x78, 0x41, 0xb2, 0x89, 0x77, 0xd1, 0xa0, 0x78, 0x71, 0x91, 0x18, 0x12, 0x50, 0xde, 0x64, + 0x1c, 0x58, 0xc7, 0x41, 0xdb, 0xc5, 0x82, 0x7c, 0x9c, 0x07, 0x85, 0x76, 0x93, 0x1d, 0xd1, 0xb4, + 0x26, 0x61, 0xe6, 0x17, 0x79, 0x46, 0x73, 0x6a, 0x54, 0x0d, 0x3e, 0xf0, 0x91, 0x85, 0x75, 0xd2, + 0x0e, 0xb1, 0xf2, 0x0d, 0xb8, 0x82, 0xda, 0x61, 0x93, 0xf8, 0x76, 0xf8, 0x64, 0x68, 0x99, 0xe8, + 0x8a, 0x2a, 0x1a, 0x4c, 0xb3, 0x63, 0x91, 0x01, 0x33, 0x49, 0x07, 0x6b, 0x51, 0x58, 0xaa, 0x50, + 0xe4, 0xa7, 0xd8, 0x08, 0x89, 0xe1, 0xe3, 0x23, 0xe4, 0x5b, 0x86, 0x2c, 0x0d, 0x55, 0x2e, 0x75, + 0x40, 0x74, 0x26, 0x53, 0x4b, 0x26, 0xe5, 0x77, 0xe1, 0x56, 0x57, 0x47, 0x48, 0x71, 0x67, 0x54, + 0xf0, 0x24, 0x5d, 0x8c, 0x55, 0x30, 0xd7, 0x52, 0x1a, 0x76, 0x81, 0x33, 0xa9, 0x2e, 0x06, 0x19, + 0xe3, 0xe1, 0xd7, 0xd6, 0x2d, 0x2a, 0x19, 0xe3, 0x38, 0xe8, 0x61, 0x37, 0x3f, 0x84, 0xe5, 0x58, + 0x45, 0x0c, 0x46, 0xa6, 0x8b, 0x73, 0xac, 0x22, 0x17, 0x8d, 0x20, 0xf5, 0x2a, 0xfb, 0x3e, 0xdc, + 0x8e, 0x54, 0x10, 0x83, 0x03, 0x94, 0xa8, 0x9a, 0x60, 0xaa, 0x5e, 0x62, 0x82, 0x07, 0x84, 0xee, + 0x6a, 0xaf, 0xa2, 0x0a, 0x2c, 0x44, 0xa8, 0x18, 0xf1, 0x33, 0x88, 0xc7, 0xf4, 0x15, 0xf2, 0x6c, + 0xed, 0x1c, 0x9f, 0x63, 0x44, 0xf0, 0xbe, 0x47, 0x35, 0x28, 0x9b, 0x70, 0x3d, 0xbb, 0x80, 0x7f, + 0x17, 0xae, 0xb0, 0x25, 0xf3, 0xa9, 0x25, 0x3c, 0x18, 0xca, 0x3a, 0x5c, 0xcb, 0x2e, 0x62, 0xa8, + 0x38, 0x57, 0xd4, 0x95, 0xd4, 0x1a, 0xe6, 0x32, 0xed, 0xb3, 0xba, 0x1c, 0xb6, 0xbb, 0x60, 0x92, + 0xf7, 0x59, 0x82, 0xd1, 0xc6, 0xe2, 0x77, 0x41, 0x49, 0x8b, 0x33, 0x2f, 0x38, 0x71, 0x9e, 0x49, + 0x48, 0x33, 0x1f, 0x6e, 0xc0, 0x44, 0x8b, 0x10, 0x16, 0xa3, 0x69, 0x7e, 0x53, 0xd1, 0xcf, 0x5d, + 0x4b, 0xd9, 0x02, 0x95, 0x72, 0x39, 0xe4, 0x38, 0xe4, 0x08, 0x5b, 0x46, 0x70, 0x84, 0x5a, 0x86, + 0x43, 0x82, 0x20, 0x41, 0xe9, 0x58, 0x57, 0xbf, 0xcd, 0x05, 0xf6, 0x8f, 0x50, 0xeb, 0x1e, 0x09, + 0x02, 0x56, 0x91, 0xde, 0x85, 0x19, 0xca, 0x3a, 0xd9, 0x9a, 0xa8, 0x5f, 0x99, 0x39, 0x57, 0xbf, + 0x32, 0xed, 0xda, 0x1e, 0xd5, 0xbc, 0xcd, 0xdb, 0x16, 0xaa, 0x17, 0x75, 0x52, 0x7a, 0x67, 0xcf, + 0xa9, 0x17, 0x75, 0xba, 0x7a, 0xb7, 0xbe, 0xf5, 0x93, 0xcf, 0x9f, 0xae, 0x76, 0x0f, 0xe5, 0xcf, + 0x3f, 0x7f, 0xba, 0xfa, 0x72, 0xf4, 0x08, 0xd5, 0xe9, 0x3e, 0x43, 0x49, 0x8e, 0x7d, 0x44, 0x20, + 0xb3, 0xc3, 0xa2, 0x5a, 0xfc, 0x35, 0xc7, 0xaa, 0x05, 0xbf, 0xa3, 0x2e, 0xa0, 0x5a, 0xdc, 0x86, + 0xa9, 0x64, 0xf2, 0xc4, 0xc5, 0x22, 0x91, 0x33, 0x43, 0x9e, 0x2b, 0x4e, 0xef, 0x6a, 0x16, 0x73, + 0xe4, 0x6a, 0x76, 0x58, 0xb8, 0xfa, 0xf7, 0x51, 0xe6, 0x2a, 0xbf, 0x37, 0xbe, 0x0c, 0xae, 0x26, + 0x53, 0x7b, 0xec, 0x0c, 0xa9, 0x3d, 0x7e, 0xd6, 0xd4, 0xbe, 0xfc, 0x7f, 0x4a, 0xed, 0x89, 0x17, + 0x9a, 0xda, 0xd9, 0x8d, 0x8b, 0xf6, 0x3b, 0x3b, 0x2c, 0xf6, 0xfb, 0x5f, 0x97, 0xd8, 0x35, 0xb9, + 0x8f, 0xc3, 0x1a, 0x71, 0xdd, 0xb6, 0x67, 0x87, 0x4f, 0xde, 0x26, 0xc4, 0xa1, 0xfc, 0x3f, 0xc4, + 0x94, 0x33, 0xa7, 0x2e, 0xde, 0x41, 0x7c, 0xee, 0x14, 0xc4, 0xe0, 0x3e, 0x4c, 0xfa, 0x4c, 0x71, + 0xf2, 0x29, 0xb4, 0x7c, 0xb6, 0x86, 0x52, 0x07, 0xae, 0x82, 0x6d, 0xe3, 0xfb, 0xb0, 0x90, 0xec, + 0x1b, 0xad, 0x38, 0xe6, 0x63, 0xe7, 0x8a, 0xb9, 0xe2, 0x74, 0x9b, 0x4c, 0x2b, 0x0a, 0xfc, 0xeb, + 0x34, 0xf0, 0xb1, 0x6f, 0x34, 0xec, 0x77, 0xa5, 0x61, 0x97, 0xc7, 0x2f, 0xe2, 0xe0, 0xf2, 0xc9, + 0x78, 0x0b, 0x36, 0x9e, 0xce, 0xc2, 0xe8, 0x5e, 0xd0, 0x50, 0x1e, 0xc0, 0x64, 0xf2, 0xe1, 0xaf, + 0xd4, 0xc3, 0xf9, 0xd3, 0xef, 0x93, 0xea, 0x57, 0x87, 0x08, 0x88, 0x47, 0xb9, 0xf7, 0xe1, 0x6a, + 0xe6, 0x51, 0x51, 0x93, 0x2e, 0x4d, 0xc9, 0xa8, 0xab, 0xc3, 0x65, 0x84, 0x85, 0x07, 0x30, 0x99, + 0x7c, 0xf9, 0x92, 0x42, 0x4f, 0x08, 0xc8, 0xa1, 0x4b, 0x9e, 0xa3, 0x94, 0x47, 0x30, 0xdb, 0xf3, + 0x14, 0x75, 0x47, 0xbe, 0x38, 0x2d, 0xa5, 0xbe, 0x72, 0x1a, 0x29, 0x61, 0xa7, 0x03, 0xd7, 0xfb, + 0x3c, 0x0f, 0x48, 0xc3, 0x20, 0x97, 0x55, 0x37, 0x4e, 0x2f, 0x2b, 0x2c, 0x13, 0x98, 0x97, 0xb5, + 0xf8, 0x7d, 0x22, 0xd4, 0x23, 0xa8, 0x56, 0x4e, 0x29, 0x28, 0x0c, 0xbe, 0x07, 0xd3, 0xe9, 0xd6, + 0xfd, 0xb6, 0x4c, 0x43, 0x4a, 0x44, 0xfd, 0xda, 0x50, 0x11, 0xa1, 0xfe, 0x08, 0xae, 0x49, 0x7b, + 0xce, 0x3e, 0x81, 0x94, 0xb6, 0xa7, 0x7d, 0x02, 0x39, 0xb0, 0x95, 0x55, 0x4c, 0x98, 0xc9, 0xb6, + 0xb1, 0xcb, 0x32, 0x35, 0x19, 0x21, 0xf5, 0xee, 0x29, 0x84, 0x84, 0x91, 0x1f, 0x43, 0xa1, 0x6f, + 0x2b, 0xda, 0x27, 0xe3, 0xe4, 0xd2, 0xea, 0xab, 0x67, 0x91, 0x16, 0xf6, 0x7f, 0x99, 0x83, 0x5b, + 0x83, 0xdb, 0xc8, 0x75, 0x99, 0xde, 0x81, 0x4b, 0xd4, 0xd7, 0xce, 0xbc, 0x24, 0x99, 0xbd, 0xb2, + 0xb6, 0x51, 0x9a, 0xbd, 0x12, 0x41, 0x79, 0xf6, 0x0e, 0xe8, 0x0f, 0x95, 0x87, 0x30, 0x95, 0xfa, + 0xa5, 0x60, 0x49, 0x7e, 0xe4, 0xba, 0x12, 0xea, 0xca, 0x30, 0x09, 0xa1, 0xfb, 0xb7, 0x39, 0x28, + 0x0d, 0xfb, 0x41, 0x70, 0xb3, 0x7f, 0xac, 0xfa, 0x2e, 0x52, 0xbf, 0x7d, 0x8e, 0x45, 0xc9, 0xea, + 0x9d, 0x69, 0x87, 0xb5, 0x3e, 0xa9, 0x93, 0x90, 0x91, 0x57, 0x6f, 0x79, 0x33, 0x4c, 0x8b, 0x6c, + 0x4f, 0x23, 0x2c, 0x2d, 0xb2, 0x59, 0x29, 0x79, 0x91, 0xed, 0x47, 0xa3, 0xa9, 0x9d, 0x1e, 0x0a, + 0x7d, 0xa7, 0xff, 0xe9, 0x1b, 0x66, 0xa7, 0x1f, 0x87, 0xa5, 0x76, 0x7a, 0xf8, 0xeb, 0x9d, 0xfe, + 0x5b, 0x30, 0xcc, 0x4e, 0x3f, 0xee, 0x44, 0x2f, 0x8d, 0x3e, 0xbc, 0x49, 0x1a, 0x7d, 0xb9, 0xac, + 0xbc, 0xd6, 0x0d, 0xa6, 0x0c, 0xd5, 0x7b, 0x9f, 0x3c, 0x2b, 0xe6, 0x3e, 0x7d, 0x56, 0xcc, 0xfd, + 0xe7, 0x59, 0x31, 0xf7, 0xeb, 0xe7, 0xc5, 0x91, 0x4f, 0x9f, 0x17, 0x47, 0xfe, 0xf1, 0xbc, 0x38, + 0xf2, 0x70, 0x23, 0xc1, 0x75, 0xf6, 0x99, 0xde, 0xb5, 0x7b, 0xa8, 0x1e, 0x54, 0x22, 0xd6, 0x72, + 0xb8, 0xfe, 0x5a, 0x92, 0xb9, 0x30, 0xee, 0x53, 0xbf, 0xcc, 0x7e, 0x12, 0xdf, 0xfc, 0x5f, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x31, 0x04, 0xe4, 0xe0, 0xdd, 0x1f, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2166,6 +2271,7 @@ type MsgClient interface { CreateTradeRoute(ctx context.Context, in *MsgCreateTradeRoute, opts ...grpc.CallOption) (*MsgCreateTradeRouteResponse, error) DeleteTradeRoute(ctx context.Context, in *MsgDeleteTradeRoute, opts ...grpc.CallOption) (*MsgDeleteTradeRouteResponse, error) UpdateTradeRoute(ctx context.Context, in *MsgUpdateTradeRoute, opts ...grpc.CallOption) (*MsgUpdateTradeRouteResponse, error) + SetCommunityPoolRebate(ctx context.Context, in *MsgSetCommunityPoolRebate, opts ...grpc.CallOption) (*MsgSetCommunityPoolRebateResponse, error) } type msgClient struct { @@ -2338,6 +2444,15 @@ func (c *msgClient) UpdateTradeRoute(ctx context.Context, in *MsgUpdateTradeRout return out, nil } +func (c *msgClient) SetCommunityPoolRebate(ctx context.Context, in *MsgSetCommunityPoolRebate, opts ...grpc.CallOption) (*MsgSetCommunityPoolRebateResponse, error) { + out := new(MsgSetCommunityPoolRebateResponse) + err := c.cc.Invoke(ctx, "/stride.stakeibc.Msg/SetCommunityPoolRebate", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { LiquidStake(context.Context, *MsgLiquidStake) (*MsgLiquidStakeResponse, error) @@ -2358,6 +2473,7 @@ type MsgServer interface { CreateTradeRoute(context.Context, *MsgCreateTradeRoute) (*MsgCreateTradeRouteResponse, error) DeleteTradeRoute(context.Context, *MsgDeleteTradeRoute) (*MsgDeleteTradeRouteResponse, error) UpdateTradeRoute(context.Context, *MsgUpdateTradeRoute) (*MsgUpdateTradeRouteResponse, error) + SetCommunityPoolRebate(context.Context, *MsgSetCommunityPoolRebate) (*MsgSetCommunityPoolRebateResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -2418,6 +2534,9 @@ func (*UnimplementedMsgServer) DeleteTradeRoute(ctx context.Context, req *MsgDel func (*UnimplementedMsgServer) UpdateTradeRoute(ctx context.Context, req *MsgUpdateTradeRoute) (*MsgUpdateTradeRouteResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateTradeRoute not implemented") } +func (*UnimplementedMsgServer) SetCommunityPoolRebate(ctx context.Context, req *MsgSetCommunityPoolRebate) (*MsgSetCommunityPoolRebateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetCommunityPoolRebate not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -2747,6 +2866,24 @@ func _Msg_UpdateTradeRoute_Handler(srv interface{}, ctx context.Context, dec fun return interceptor(ctx, in, info, handler) } +func _Msg_SetCommunityPoolRebate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgSetCommunityPoolRebate) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).SetCommunityPoolRebate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/stride.stakeibc.Msg/SetCommunityPoolRebate", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).SetCommunityPoolRebate(ctx, req.(*MsgSetCommunityPoolRebate)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "stride.stakeibc.Msg", HandlerType: (*MsgServer)(nil), @@ -2823,6 +2960,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "UpdateTradeRoute", Handler: _Msg_UpdateTradeRoute_Handler, }, + { + MethodName: "SetCommunityPoolRebate", + Handler: _Msg_SetCommunityPoolRebate_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "stride/stakeibc/tx.proto", @@ -4330,6 +4471,86 @@ func (m *MsgUpdateTradeRouteResponse) MarshalToSizedBuffer(dAtA []byte) (int, er return len(dAtA) - i, nil } +func (m *MsgSetCommunityPoolRebate) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgSetCommunityPoolRebate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSetCommunityPoolRebate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.LiquidStakedAmount.Size() + i -= size + if _, err := m.LiquidStakedAmount.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + { + size := m.RebateRate.Size() + i -= size + if _, err := m.RebateRate.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintTx(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0x12 + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgSetCommunityPoolRebateResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgSetCommunityPoolRebateResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSetCommunityPoolRebateResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func encodeVarintTx(dAtA []byte, offset int, v uint64) int { offset -= sovTx(v) base := offset @@ -4988,6 +5209,36 @@ func (m *MsgUpdateTradeRouteResponse) Size() (n int) { return n } +func (m *MsgSetCommunityPoolRebate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.RebateRate.Size() + n += 1 + l + sovTx(uint64(l)) + l = m.LiquidStakedAmount.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgSetCommunityPoolRebateResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func sovTx(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -9523,6 +9774,238 @@ func (m *MsgUpdateTradeRouteResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgSetCommunityPoolRebate) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSetCommunityPoolRebate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSetCommunityPoolRebate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChainId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RebateRate", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.RebateRate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LiquidStakedAmount", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.LiquidStakedAmount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgSetCommunityPoolRebateResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSetCommunityPoolRebateResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSetCommunityPoolRebateResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 From 24a1367a36012567b94c63c7a363754f904ddd1e Mon Sep 17 00:00:00 2001 From: sampocs Date: Tue, 19 Mar 2024 16:01:10 -0500 Subject: [PATCH 07/13] added toggle trade controller tx (#1142) --- proto/stride/stakeibc/tx.proto | 25 + x/stakeibc/client/cli/tx.go | 1 + .../client/cli/tx_toggle_trade_controller.go | 52 ++ x/stakeibc/handler.go | 3 + x/stakeibc/keeper/msg_server.go | 45 + x/stakeibc/keeper/msg_server_test.go | 60 ++ x/stakeibc/keeper/reward_converter.go | 36 + x/stakeibc/keeper/reward_converter_test.go | 48 ++ x/stakeibc/keeper/trade_route.go | 10 + x/stakeibc/keeper/trade_route_test.go | 33 + x/stakeibc/types/codec.go | 2 + .../message_set_community_pool_rebate_test.go | 18 +- .../types/message_toggle_trade_controller.go | 67 ++ .../message_toggle_trade_controller_test.go | 104 +++ x/stakeibc/types/tx.pb.go | 777 +++++++++++++++--- 15 files changed, 1135 insertions(+), 146 deletions(-) create mode 100644 x/stakeibc/client/cli/tx_toggle_trade_controller.go create mode 100644 x/stakeibc/types/message_toggle_trade_controller.go create mode 100644 x/stakeibc/types/message_toggle_trade_controller_test.go diff --git a/proto/stride/stakeibc/tx.proto b/proto/stride/stakeibc/tx.proto index d6424471b5..529172dd6d 100644 --- a/proto/stride/stakeibc/tx.proto +++ b/proto/stride/stakeibc/tx.proto @@ -43,6 +43,8 @@ service Msg { returns (MsgUpdateTradeRouteResponse); rpc SetCommunityPoolRebate(MsgSetCommunityPoolRebate) returns (MsgSetCommunityPoolRebateResponse); + rpc ToggleTradeController(MsgToggleTradeController) + returns (MsgToggleTradeControllerResponse); } message MsgUpdateInnerRedemptionRateBounds { @@ -340,3 +342,26 @@ message MsgSetCommunityPoolRebate { ]; } message MsgSetCommunityPoolRebateResponse {} + +enum AuthzPermissionChange { + // Grant the address trade permissions + GRANT = 0; + // Revoke trade permissions from the address + REVOKE = 1; +} + +// Grants or revokes trade permissions to a given address via authz +message MsgToggleTradeController { + option (cosmos.msg.v1.signer) = "creator"; + option (amino.name) = "stride/x/stakeibc/MsgToggleTradeController"; + + // Message signer (admin only) + string creator = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + // Chain ID of the trade account + string chain_id = 2; + // Permission change (either grant or revoke) + AuthzPermissionChange permission_change = 3; + // Address of trade operator + string address = 4; +} +message MsgToggleTradeControllerResponse {} diff --git a/x/stakeibc/client/cli/tx.go b/x/stakeibc/client/cli/tx.go index a2abed08e2..f6eaf272aa 100644 --- a/x/stakeibc/client/cli/tx.go +++ b/x/stakeibc/client/cli/tx.go @@ -41,6 +41,7 @@ func GetTxCmd() *cobra.Command { cmd.AddCommand(CmdUpdateInnerRedemptionRateBounds()) cmd.AddCommand(CmdResumeHostZone()) cmd.AddCommand(CmdSetCommunityPoolRebate()) + cmd.AddCommand(CmdToggleTradeController()) return cmd } diff --git a/x/stakeibc/client/cli/tx_toggle_trade_controller.go b/x/stakeibc/client/cli/tx_toggle_trade_controller.go new file mode 100644 index 0000000000..9b24243345 --- /dev/null +++ b/x/stakeibc/client/cli/tx_toggle_trade_controller.go @@ -0,0 +1,52 @@ +package cli + +import ( + "errors" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/spf13/cobra" + + "github.com/Stride-Labs/stride/v19/x/stakeibc/types" +) + +func CmdToggleTradeController() *cobra.Command { + cmd := &cobra.Command{ + Use: "toggle-trade-controller [chain-id] [grant|revoke] [address]", + Short: "Submits an ICA tx to grant or revoke permissions to trade on behalf of the trade ICA", + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) (err error) { + chainId := args[0] + permissionChangeString := args[1] + address := args[2] + + permissionChangeInt, ok := types.AuthzPermissionChange_value[strings.ToUpper(permissionChangeString)] + if !ok { + return errors.New("invalid permission change, must be either 'grant' or 'revoke'") + } + permissionChange := types.AuthzPermissionChange(permissionChangeInt) + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msg := types.NewMsgToggleTradeController( + clientCtx.GetFromAddress().String(), + chainId, + permissionChange, + address, + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/stakeibc/handler.go b/x/stakeibc/handler.go index 43f3aefbae..9d36ee8868 100644 --- a/x/stakeibc/handler.go +++ b/x/stakeibc/handler.go @@ -80,6 +80,9 @@ func NewMessageHandler(k keeper.Keeper) sdk.Handler { case *types.MsgSetCommunityPoolRebate: res, err := msgServer.SetCommunityPoolRebate(sdk.WrapSDKContext(ctx), msg) return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgToggleTradeController: + res, err := msgServer.ToggleTradeController(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) default: errMsg := fmt.Sprintf("unrecognized %s message type: %T", types.ModuleName, msg) return nil, errorsmod.Wrap(sdkerrors.ErrUnknownRequest, errMsg) diff --git a/x/stakeibc/keeper/msg_server.go b/x/stakeibc/keeper/msg_server.go index 0d53345d8a..987b21ceb4 100644 --- a/x/stakeibc/keeper/msg_server.go +++ b/x/stakeibc/keeper/msg_server.go @@ -3,6 +3,7 @@ package keeper import ( "context" "fmt" + "time" errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" @@ -1131,3 +1132,47 @@ func (k msgServer) SetCommunityPoolRebate( return &types.MsgSetCommunityPoolRebateResponse{}, nil } + +// Submits an ICA tx to either grant or revoke authz permisssions to an address +// to execute trades on behalf of the trade ICA +func (k msgServer) ToggleTradeController( + goCtx context.Context, + msg *types.MsgToggleTradeController, +) (*types.MsgToggleTradeControllerResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + // Fetch the trade ICA which will be the granter + tradeRoute, found := k.GetTradeRouteFromTradeAccountChainId(ctx, msg.ChainId) + if !found { + return nil, types.ErrTradeRouteNotFound.Wrapf("trade route not found for chain ID %s", msg.ChainId) + } + + // Build the authz message that grants or revokes trade permissions to the specified address + authzMsg, err := k.BuildTradeAuthzMsg(ctx, tradeRoute, msg.PermissionChange, msg.Address) + if err != nil { + return nil, err + } + + // Build the ICA channel owner from the trade route + tradeRouteAccountOwner := types.FormatTradeRouteICAOwnerFromRouteId( + msg.ChainId, + tradeRoute.GetRouteId(), + types.ICAAccountType_CONVERTER_TRADE, + ) + + // Submit the ICA tx from the trade ICA account + // Timeout the ICA at 1 hour + timeoutTimestamp := uint64(ctx.BlockTime().Add(time.Hour).UnixNano()) + err = k.SubmitICATxWithoutCallback( + ctx, + tradeRoute.TradeAccount.ConnectionId, + tradeRouteAccountOwner, + authzMsg, + timeoutTimestamp, + ) + if err != nil { + return nil, err + } + + return &types.MsgToggleTradeControllerResponse{}, nil +} diff --git a/x/stakeibc/keeper/msg_server_test.go b/x/stakeibc/keeper/msg_server_test.go index 26510fe366..660a108d6c 100644 --- a/x/stakeibc/keeper/msg_server_test.go +++ b/x/stakeibc/keeper/msg_server_test.go @@ -2620,3 +2620,63 @@ func (s *KeeperTestSuite) TestSetCommunityPoolRebate() { _, err = s.GetMsgServer().SetCommunityPoolRebate(s.Ctx, &types.MsgSetCommunityPoolRebate{ChainId: "invalid"}) s.Require().ErrorContains(err, "host zone not found") } + +// ---------------------------------------------------- +// ToggleTradeController +// ---------------------------------------------------- + +func (s *KeeperTestSuite) TestToggleTradeController() { + tradeICAOwner := types.FormatTradeRouteICAOwner(HostChainId, RewardDenom, HostDenom, types.ICAAccountType_CONVERTER_TRADE) + channelId, portId := s.CreateICAChannel(tradeICAOwner) + + tradeControllerAddress := "trade-controller" + + // Create a trade route + tradeRoute := types.TradeRoute{ + RewardDenomOnRewardZone: RewardDenom, + HostDenomOnHostZone: HostDenom, + TradeAccount: types.ICAAccount{ + ChainId: HostChainId, + ConnectionId: ibctesting.FirstConnectionID, + }, + } + s.App.StakeibcKeeper.SetTradeRoute(s.Ctx, tradeRoute) + + // Test granting permissions + grantMsg := types.MsgToggleTradeController{ + ChainId: HostChainId, + PermissionChange: types.AuthzPermissionChange_GRANT, + Address: tradeControllerAddress, + } + s.CheckICATxSubmitted(portId, channelId, func() error { + _, err := s.GetMsgServer().ToggleTradeController(s.Ctx, &grantMsg) + return err + }) + + // Test revoking permissions + revokeMsg := types.MsgToggleTradeController{ + ChainId: HostChainId, + PermissionChange: types.AuthzPermissionChange_REVOKE, + Address: tradeControllerAddress, + } + s.CheckICATxSubmitted(portId, channelId, func() error { + _, err := s.GetMsgServer().ToggleTradeController(s.Ctx, &revokeMsg) + return err + }) + + // Test with an invalid chain ID - it should fail because the trade route cant be found + invalidMsg := &types.MsgToggleTradeController{ChainId: "invalid-chain"} + _, err := s.GetMsgServer().ToggleTradeController(s.Ctx, invalidMsg) + s.Require().ErrorContains(err, "trade route not found") + + // Test failing to build an authz message by passing an invalid permission change + invalidMsg = &types.MsgToggleTradeController{ChainId: HostChainId, PermissionChange: 100} + _, err = s.GetMsgServer().ToggleTradeController(s.Ctx, invalidMsg) + s.Require().ErrorContains(err, "invalid permission change") + + // Remove the connection ID from the trade route so the ICA submission fails + tradeRoute.TradeAccount.ConnectionId = "" + s.App.StakeibcKeeper.SetTradeRoute(s.Ctx, tradeRoute) + _, err = s.GetMsgServer().ToggleTradeController(s.Ctx, &grantMsg) + s.Require().ErrorContains(err, "unable to send ICA tx") +} diff --git a/x/stakeibc/keeper/reward_converter.go b/x/stakeibc/keeper/reward_converter.go index 4730538516..35d16050bd 100644 --- a/x/stakeibc/keeper/reward_converter.go +++ b/x/stakeibc/keeper/reward_converter.go @@ -2,6 +2,7 @@ package keeper import ( "encoding/json" + "errors" "fmt" "time" @@ -9,6 +10,7 @@ import ( sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/bech32" + "github.com/cosmos/cosmos-sdk/x/authz" bankTypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/gogoproto/proto" @@ -51,6 +53,40 @@ type ForwardMetadata struct { // and the normal staking and distribution flow will continue from there. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Builds an authz MsgGrant or MsgRevoke to grant an account trade capabilties on behalf of the trade ICA +func (k Keeper) BuildTradeAuthzMsg( + ctx sdk.Context, + tradeRoute types.TradeRoute, + permissionChange types.AuthzPermissionChange, + grantee string, +) (authzMsg []proto.Message, err error) { + swapMsgTypeUrl := "/" + proto.MessageName(&types.MsgSwapExactAmountIn{}) + + switch permissionChange { + case types.AuthzPermissionChange_GRANT: + authorization := authz.NewGenericAuthorization(swapMsgTypeUrl) + grant, err := authz.NewGrant(ctx.BlockTime(), authorization, nil) + if err != nil { + return nil, errorsmod.Wrapf(err, "unable to build grant struct") + } + authzMsg = []proto.Message{&authz.MsgGrant{ + Granter: tradeRoute.TradeAccount.Address, + Grantee: grantee, + Grant: grant, + }} + case types.AuthzPermissionChange_REVOKE: + authzMsg = []proto.Message{&authz.MsgRevoke{ + Granter: tradeRoute.TradeAccount.Address, + Grantee: grantee, + MsgTypeUrl: swapMsgTypeUrl, + }} + default: + return nil, errors.New("invalid permission change") + } + + return authzMsg, nil +} + // Builds a PFM transfer message to send reward tokens from the host zone, // through the reward zone (to unwind) and finally to the trade zone func (k Keeper) BuildHostToTradeTransferMsg( diff --git a/x/stakeibc/keeper/reward_converter_test.go b/x/stakeibc/keeper/reward_converter_test.go index f4ea1ccf9c..e788c08b66 100644 --- a/x/stakeibc/keeper/reward_converter_test.go +++ b/x/stakeibc/keeper/reward_converter_test.go @@ -6,6 +6,7 @@ import ( sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/authz" "github.com/cosmos/gogoproto/proto" transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ibctesting "github.com/cosmos/ibc-go/v7/testing" @@ -33,6 +34,53 @@ type TransferRewardHostToTradeTestCase struct { PortID string } +// -------------------------------------------------------------- +// BuildTradeAuthzMsg +// -------------------------------------------------------------- + +func (s *KeeperTestSuite) TestBuildTradeAuthzMsg() { + granterAddress := "trade_ica" + granteeAddress := "trade_controller" + + tradeRoute := types.TradeRoute{ + TradeAccount: types.ICAAccount{ + Address: granterAddress, + }, + } + + expectedTypeUrl := "/osmosis.gamm.v1beta1.MsgSwapExactAmountIn" + + // Test granting trade permissions + msgs, err := s.App.StakeibcKeeper.BuildTradeAuthzMsg(s.Ctx, tradeRoute, types.AuthzPermissionChange_GRANT, granteeAddress) + s.Require().NoError(err, "no error expected when building grant message") + s.Require().Len(msgs, 1, "there should be one message") + + grantMsg, ok := msgs[0].(*authz.MsgGrant) + s.Require().True(ok, "message should be of type grant") + s.Require().Equal(granterAddress, grantMsg.Granter, "granter of grant message") + s.Require().Equal(granteeAddress, grantMsg.Grantee, "grantee of grant message") + + authorization, err := grantMsg.Grant.GetAuthorization() + s.Require().NoError(err) + s.Require().Equal(expectedTypeUrl, authorization.MsgTypeURL(), "grant msg type url") + s.Require().Nil(grantMsg.Grant.Expiration, "expiration should be nil") + + // Test revoking trade permissions + msgs, err = s.App.StakeibcKeeper.BuildTradeAuthzMsg(s.Ctx, tradeRoute, types.AuthzPermissionChange_REVOKE, granteeAddress) + s.Require().NoError(err, "no error expected when building revoke message") + s.Require().Len(msgs, 1, "there should be one message") + + revokeMsg, ok := msgs[0].(*authz.MsgRevoke) + s.Require().True(ok, "message should be of type revoke") + s.Require().Equal(granterAddress, revokeMsg.Granter, "granter of revoke message") + s.Require().Equal(granteeAddress, revokeMsg.Grantee, "grantee of revoke message") + s.Require().Equal(expectedTypeUrl, revokeMsg.MsgTypeUrl, "revoke msg type url") + + // Test invalid permissions + _, err = s.App.StakeibcKeeper.BuildTradeAuthzMsg(s.Ctx, tradeRoute, 100, granteeAddress) + s.Require().ErrorContains(err, "invalid permission change") +} + // -------------------------------------------------------------- // Transfer Host to Trade // -------------------------------------------------------------- diff --git a/x/stakeibc/keeper/trade_route.go b/x/stakeibc/keeper/trade_route.go index a1b7db9b9c..90e7441f3c 100644 --- a/x/stakeibc/keeper/trade_route.go +++ b/x/stakeibc/keeper/trade_route.go @@ -51,3 +51,13 @@ func (k Keeper) GetAllTradeRoutes(ctx sdk.Context) (list []types.TradeRoute) { return } + +// Searches for a trade route by the trade account chain ID +func (k Keeper) GetTradeRouteFromTradeAccountChainId(ctx sdk.Context, chainId string) (tradeRoute types.TradeRoute, found bool) { + for _, tradeRoute := range k.GetAllTradeRoutes(ctx) { + if tradeRoute.TradeAccount.ChainId == chainId { + return tradeRoute, true + } + } + return tradeRoute, false +} diff --git a/x/stakeibc/keeper/trade_route_test.go b/x/stakeibc/keeper/trade_route_test.go index 6498bdd2eb..2651ded1e4 100644 --- a/x/stakeibc/keeper/trade_route_test.go +++ b/x/stakeibc/keeper/trade_route_test.go @@ -96,3 +96,36 @@ func (s *KeeperTestSuite) TestGetAllTradeRoutes() { actualRoutes := s.App.StakeibcKeeper.GetAllTradeRoutes(s.Ctx) s.Require().ElementsMatch(expectedRoutes, actualRoutes) } + +func (s *KeeperTestSuite) TestGetTradeRouteFromTradeAccountChainId() { + // Store 3 trade routes + for i := 1; i <= 3; i++ { + rewardDenom := fmt.Sprintf("reward-%d", i) + hostDenom := fmt.Sprintf("host-%d", i) + chainId := fmt.Sprintf("chain-%d", i) + + s.App.StakeibcKeeper.SetTradeRoute(s.Ctx, types.TradeRoute{ + RewardDenomOnRewardZone: rewardDenom, + HostDenomOnHostZone: hostDenom, + TradeAccount: types.ICAAccount{ + ChainId: chainId, + }, + }) + } + + // Search for each of them by chain ID + for i := 1; i <= 3; i++ { + rewardDenom := fmt.Sprintf("reward-%d", i) + hostDenom := fmt.Sprintf("host-%d", i) + chainId := fmt.Sprintf("chain-%d", i) + + actualRoute, found := s.App.StakeibcKeeper.GetTradeRouteFromTradeAccountChainId(s.Ctx, chainId) + s.Require().True(found, "trade route 1 should have been found") + s.Require().Equal(actualRoute.RewardDenomOnRewardZone, rewardDenom, "reward denom") + s.Require().Equal(actualRoute.HostDenomOnHostZone, hostDenom, "host denom") + } + + // Search for a chainId without a trade route + _, found := s.App.StakeibcKeeper.GetTradeRouteFromTradeAccountChainId(s.Ctx, "chain-4") + s.Require().False(found, "trade route should not have been found") +} diff --git a/x/stakeibc/types/codec.go b/x/stakeibc/types/codec.go index 3be3ff8c76..7aa4454df6 100644 --- a/x/stakeibc/types/codec.go +++ b/x/stakeibc/types/codec.go @@ -27,6 +27,7 @@ func RegisterCodec(cdc *codec.LegacyAmino) { cdc.RegisterConcrete(&MsgUpdateInnerRedemptionRateBounds{}, "stakeibc/UpdateInnerRedemptionRateBounds", nil) cdc.RegisterConcrete(&MsgResumeHostZone{}, "stakeibc/ResumeHostZone", nil) cdc.RegisterConcrete(&MsgSetCommunityPoolRebate{}, "stakeibc/SetCommunityPoolRebate", nil) + cdc.RegisterConcrete(&MsgToggleTradeController{}, "stakeibc/ToggleTradeController", nil) } func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { @@ -46,6 +47,7 @@ func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { &MsgUpdateInnerRedemptionRateBounds{}, &MsgResumeHostZone{}, &MsgSetCommunityPoolRebate{}, + &MsgToggleTradeController{}, ) registry.RegisterImplementations((*govtypes.Content)(nil), diff --git a/x/stakeibc/types/message_set_community_pool_rebate_test.go b/x/stakeibc/types/message_set_community_pool_rebate_test.go index 115f847e90..62998e4606 100644 --- a/x/stakeibc/types/message_set_community_pool_rebate_test.go +++ b/x/stakeibc/types/message_set_community_pool_rebate_test.go @@ -68,26 +68,26 @@ func TestMsgSetCommunityPoolRebate(t *testing.T) { err: "chain ID must be specified", }, { - name: "invalid rebate percentage - nil", + name: "invalid rebate rate - nil", msg: types.MsgSetCommunityPoolRebate{ Creator: validAdminAddress, ChainId: validChainId, LiquidStakedAmount: validLiquidStakedAmount, }, - err: "rebate percentage, must be between 0 and 1 (inclusive)", + err: "rebate rate, must be a decimal between 0 and 1 (inclusive)", }, { - name: "invalid rebate percentage - less than 0", + name: "invalid rebate rate - less than 0", msg: types.MsgSetCommunityPoolRebate{ Creator: validAdminAddress, ChainId: validChainId, RebateRate: sdk.MustNewDecFromStr("0.5").Neg(), LiquidStakedAmount: validLiquidStakedAmount, }, - err: "rebate percentage, must be between 0 and 1 (inclusive)", + err: "rebate rate, must be a decimal between 0 and 1 (inclusive)", }, { - name: "valid rebate percentage - one", + name: "valid rebate rate - one", msg: types.MsgSetCommunityPoolRebate{ Creator: validAdminAddress, ChainId: validChainId, @@ -96,14 +96,14 @@ func TestMsgSetCommunityPoolRebate(t *testing.T) { }, }, { - name: "invalid rebate percentage - greater than one", + name: "invalid rebate rate - greater than one", msg: types.MsgSetCommunityPoolRebate{ Creator: validAdminAddress, ChainId: validChainId, RebateRate: sdk.MustNewDecFromStr("1.1"), LiquidStakedAmount: validLiquidStakedAmount, }, - err: "rebate percentage, must be between 0 and 1 (inclusive)", + err: "rebate rate, must be a decimal between 0 and 1 (inclusive)", }, { name: "valid zero rebate", @@ -121,7 +121,7 @@ func TestMsgSetCommunityPoolRebate(t *testing.T) { ChainId: validChainId, RebateRate: validRebateRate, }, - err: "invalid liquid stake amount, must be greater than or equal to 0", + err: "invalid liquid stake amount, must be greater than or equal to zero", }, { name: "invalid liquid stake amount - less than 0", @@ -131,7 +131,7 @@ func TestMsgSetCommunityPoolRebate(t *testing.T) { RebateRate: validRebateRate, LiquidStakedAmount: sdkmath.NewInt(1).Neg(), }, - err: "invalid liquid stake amount, must be greater than or equal to 0", + err: "invalid liquid stake amount, must be greater than or equal to zero", }, { name: "valid liquid stake amount - zero", diff --git a/x/stakeibc/types/message_toggle_trade_controller.go b/x/stakeibc/types/message_toggle_trade_controller.go new file mode 100644 index 0000000000..1d7cafcd6b --- /dev/null +++ b/x/stakeibc/types/message_toggle_trade_controller.go @@ -0,0 +1,67 @@ +package types + +import ( + "errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + + errorsmod "cosmossdk.io/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + "github.com/Stride-Labs/stride/v19/utils" +) + +const TypeMsgToggleTradeController = "toggle_trade_controller" + +var _ sdk.Msg = &MsgToggleTradeController{} + +func NewMsgToggleTradeController(creator, chainId string, permissionChange AuthzPermissionChange, address string) *MsgToggleTradeController { + return &MsgToggleTradeController{ + Creator: creator, + ChainId: chainId, + PermissionChange: permissionChange, + Address: address, + } +} + +func (msg *MsgToggleTradeController) Route() string { + return RouterKey +} + +func (msg *MsgToggleTradeController) Type() string { + return TypeMsgToggleTradeController +} + +func (msg *MsgToggleTradeController) GetSigners() []sdk.AccAddress { + creator, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{creator} +} + +func (msg *MsgToggleTradeController) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgToggleTradeController) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + } + if err := utils.ValidateAdminAddress(msg.Creator); err != nil { + return err + } + if msg.ChainId == "" { + return errors.New("chain ID must be specified") + } + if msg.Address == "" { + return errors.New("trade controller address must be specified") + } + if _, ok := AuthzPermissionChange_name[int32(msg.PermissionChange)]; !ok { + return errors.New("invalid permission change enum value") + } + + return nil +} diff --git a/x/stakeibc/types/message_toggle_trade_controller_test.go b/x/stakeibc/types/message_toggle_trade_controller_test.go new file mode 100644 index 0000000000..87c2c85ffa --- /dev/null +++ b/x/stakeibc/types/message_toggle_trade_controller_test.go @@ -0,0 +1,104 @@ +package types_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/Stride-Labs/stride/v19/app/apptesting" + "github.com/Stride-Labs/stride/v19/x/stakeibc/types" +) + +func TestMsgToggleTradeController(t *testing.T) { + apptesting.SetupConfig() + + validNotAdminAddress, invalidAddress := apptesting.GenerateTestAddrs() + validAdminAddress, ok := apptesting.GetAdminAddress() + require.True(t, ok) + + validAddress := "cosmosXXX" + validChainId := "chain-0" + validPermissionChange := types.AuthzPermissionChange_GRANT + + tests := []struct { + name string + msg types.MsgToggleTradeController + err string + }{ + { + name: "valid message", + msg: types.MsgToggleTradeController{ + Creator: validAdminAddress, + ChainId: validChainId, + PermissionChange: validPermissionChange, + Address: validAddress, + }, + }, + { + name: "invalid address", + msg: types.MsgToggleTradeController{ + Creator: invalidAddress, + ChainId: validChainId, + PermissionChange: validPermissionChange, + Address: validAddress, + }, + err: "invalid creator address", + }, + { + name: "not admin address", + msg: types.MsgToggleTradeController{ + Creator: validNotAdminAddress, + ChainId: validChainId, + PermissionChange: validPermissionChange, + Address: validAddress, + }, + err: "not an admin", + }, + { + name: "invalid address", + msg: types.MsgToggleTradeController{ + Creator: validAdminAddress, + ChainId: validChainId, + PermissionChange: validPermissionChange, + Address: "", + }, + err: "address must be specified", + }, + { + name: "invalid chain ID", + msg: types.MsgToggleTradeController{ + Creator: validAdminAddress, + ChainId: "", + PermissionChange: validPermissionChange, + Address: validAddress, + }, + err: "chain ID must be specified", + }, + { + name: "invalid permission change", + msg: types.MsgToggleTradeController{ + Creator: validAdminAddress, + ChainId: validChainId, + PermissionChange: 100, + Address: validAddress, + }, + err: "invalid permission change enum value", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if test.err == "" { + require.NoError(t, test.msg.ValidateBasic(), "test: %v", test.name) + require.Equal(t, test.msg.Route(), types.RouterKey) + require.Equal(t, test.msg.Type(), "toggle_trade_controller") + + signers := test.msg.GetSigners() + require.Equal(t, len(signers), 1) + require.Equal(t, signers[0].String(), validAdminAddress) + } else { + require.ErrorContains(t, test.msg.ValidateBasic(), test.err, "test: %v", test.name) + } + }) + } +} diff --git a/x/stakeibc/types/tx.pb.go b/x/stakeibc/types/tx.pb.go index 13b0cca22b..13c0d4f8dc 100644 --- a/x/stakeibc/types/tx.pb.go +++ b/x/stakeibc/types/tx.pb.go @@ -33,6 +33,33 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +type AuthzPermissionChange int32 + +const ( + // Grant the address trade permissions + AuthzPermissionChange_GRANT AuthzPermissionChange = 0 + // Revoke trade permissions from the address + AuthzPermissionChange_REVOKE AuthzPermissionChange = 1 +) + +var AuthzPermissionChange_name = map[int32]string{ + 0: "GRANT", + 1: "REVOKE", +} + +var AuthzPermissionChange_value = map[string]int32{ + "GRANT": 0, + "REVOKE": 1, +} + +func (x AuthzPermissionChange) String() string { + return proto.EnumName(AuthzPermissionChange_name, int32(x)) +} + +func (AuthzPermissionChange) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_9b7e09c9ad51cd54, []int{0} +} + type MsgUpdateInnerRedemptionRateBounds struct { Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` ChainId string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` @@ -2057,7 +2084,117 @@ func (m *MsgSetCommunityPoolRebateResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgSetCommunityPoolRebateResponse proto.InternalMessageInfo +// Grants or revokes trade permissions to a given address via authz +type MsgToggleTradeController struct { + // Message signer (admin only) + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` + // Chain ID of the trade account + ChainId string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // Permission change (either grant or revoke) + PermissionChange AuthzPermissionChange `protobuf:"varint,3,opt,name=permission_change,json=permissionChange,proto3,enum=stride.stakeibc.AuthzPermissionChange" json:"permission_change,omitempty"` + // Address of trade operator + Address string `protobuf:"bytes,4,opt,name=address,proto3" json:"address,omitempty"` +} + +func (m *MsgToggleTradeController) Reset() { *m = MsgToggleTradeController{} } +func (m *MsgToggleTradeController) String() string { return proto.CompactTextString(m) } +func (*MsgToggleTradeController) ProtoMessage() {} +func (*MsgToggleTradeController) Descriptor() ([]byte, []int) { + return fileDescriptor_9b7e09c9ad51cd54, []int{39} +} +func (m *MsgToggleTradeController) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgToggleTradeController) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgToggleTradeController.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgToggleTradeController) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgToggleTradeController.Merge(m, src) +} +func (m *MsgToggleTradeController) XXX_Size() int { + return m.Size() +} +func (m *MsgToggleTradeController) XXX_DiscardUnknown() { + xxx_messageInfo_MsgToggleTradeController.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgToggleTradeController proto.InternalMessageInfo + +func (m *MsgToggleTradeController) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *MsgToggleTradeController) GetChainId() string { + if m != nil { + return m.ChainId + } + return "" +} + +func (m *MsgToggleTradeController) GetPermissionChange() AuthzPermissionChange { + if m != nil { + return m.PermissionChange + } + return AuthzPermissionChange_GRANT +} + +func (m *MsgToggleTradeController) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +type MsgToggleTradeControllerResponse struct { +} + +func (m *MsgToggleTradeControllerResponse) Reset() { *m = MsgToggleTradeControllerResponse{} } +func (m *MsgToggleTradeControllerResponse) String() string { return proto.CompactTextString(m) } +func (*MsgToggleTradeControllerResponse) ProtoMessage() {} +func (*MsgToggleTradeControllerResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_9b7e09c9ad51cd54, []int{40} +} +func (m *MsgToggleTradeControllerResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgToggleTradeControllerResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgToggleTradeControllerResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgToggleTradeControllerResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgToggleTradeControllerResponse.Merge(m, src) +} +func (m *MsgToggleTradeControllerResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgToggleTradeControllerResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgToggleTradeControllerResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgToggleTradeControllerResponse proto.InternalMessageInfo + func init() { + proto.RegisterEnum("stride.stakeibc.AuthzPermissionChange", AuthzPermissionChange_name, AuthzPermissionChange_value) proto.RegisterType((*MsgUpdateInnerRedemptionRateBounds)(nil), "stride.stakeibc.MsgUpdateInnerRedemptionRateBounds") proto.RegisterType((*MsgUpdateInnerRedemptionRateBoundsResponse)(nil), "stride.stakeibc.MsgUpdateInnerRedemptionRateBoundsResponse") proto.RegisterType((*MsgLiquidStake)(nil), "stride.stakeibc.MsgLiquidStake") @@ -2097,148 +2234,158 @@ func init() { proto.RegisterType((*MsgUpdateTradeRouteResponse)(nil), "stride.stakeibc.MsgUpdateTradeRouteResponse") proto.RegisterType((*MsgSetCommunityPoolRebate)(nil), "stride.stakeibc.MsgSetCommunityPoolRebate") proto.RegisterType((*MsgSetCommunityPoolRebateResponse)(nil), "stride.stakeibc.MsgSetCommunityPoolRebateResponse") + proto.RegisterType((*MsgToggleTradeController)(nil), "stride.stakeibc.MsgToggleTradeController") + proto.RegisterType((*MsgToggleTradeControllerResponse)(nil), "stride.stakeibc.MsgToggleTradeControllerResponse") } func init() { proto.RegisterFile("stride/stakeibc/tx.proto", fileDescriptor_9b7e09c9ad51cd54) } var fileDescriptor_9b7e09c9ad51cd54 = []byte{ - // 2172 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x59, 0xd1, 0x6f, 0x1c, 0x47, - 0x19, 0xf7, 0xc5, 0x76, 0x7c, 0xf9, 0x6c, 0xc7, 0xf6, 0xda, 0x49, 0xce, 0x9b, 0xe6, 0xce, 0x59, - 0xa7, 0x60, 0x9c, 0xfa, 0x0e, 0xdb, 0x15, 0x50, 0x53, 0x24, 0x7c, 0xe7, 0x42, 0x0d, 0x71, 0x53, - 0xad, 0xdd, 0x46, 0x8a, 0x54, 0x6d, 0xe7, 0x76, 0x27, 0x77, 0xab, 0xec, 0xee, 0x5c, 0x77, 0xf7, - 0xec, 0x0b, 0x0f, 0xa8, 0x42, 0x42, 0x42, 0x08, 0x04, 0x88, 0x57, 0x1e, 0x8a, 0xc4, 0x03, 0x82, - 0x97, 0x08, 0xf5, 0x8f, 0x28, 0x42, 0x42, 0x55, 0x9f, 0x10, 0x48, 0x06, 0x25, 0x0f, 0xe5, 0xd9, - 0x7f, 0x01, 0x9a, 0x99, 0xdd, 0xb9, 0xdd, 0xbd, 0xb9, 0x3b, 0xdb, 0x35, 0x51, 0x5f, 0x12, 0xef, - 0xcc, 0x37, 0xdf, 0xf7, 0xfb, 0xbe, 0xf9, 0xe6, 0x9b, 0xdf, 0x37, 0x07, 0x85, 0x20, 0xf4, 0x6d, - 0x0b, 0x57, 0x82, 0x10, 0x3d, 0xc6, 0x76, 0xdd, 0xac, 0x84, 0x9d, 0x72, 0xcb, 0x27, 0x21, 0x51, - 0x66, 0xf8, 0x4c, 0x39, 0x9e, 0x51, 0x4b, 0x59, 0xd1, 0x43, 0xe4, 0xd8, 0x16, 0x0a, 0x89, 0xcf, - 0x57, 0xa8, 0x0b, 0x0d, 0xd2, 0x20, 0xec, 0xcf, 0x0a, 0xfd, 0x2b, 0x1a, 0x5d, 0x34, 0x49, 0xe0, - 0x92, 0xc0, 0xe0, 0x13, 0xfc, 0x23, 0x9a, 0x2a, 0xf2, 0xaf, 0x4a, 0x1d, 0x05, 0xb8, 0x72, 0xb8, - 0x5e, 0xc7, 0x21, 0x5a, 0xaf, 0x98, 0xc4, 0xf6, 0xa2, 0xf9, 0x1b, 0xd1, 0xbc, 0x1b, 0x34, 0x2a, - 0x87, 0xeb, 0xf4, 0xbf, 0x68, 0x62, 0x0e, 0xb9, 0xb6, 0x47, 0x2a, 0xec, 0x5f, 0x3e, 0xa4, 0xfd, - 0xed, 0x12, 0x68, 0x7b, 0x41, 0xe3, 0x9d, 0x96, 0x85, 0x42, 0xbc, 0xeb, 0x79, 0xd8, 0xd7, 0xb1, - 0x85, 0xdd, 0x56, 0x68, 0x13, 0x4f, 0x47, 0x21, 0xae, 0x92, 0xb6, 0x67, 0x05, 0x4a, 0x01, 0x26, - 0x4c, 0x1f, 0x53, 0xd0, 0x85, 0xdc, 0x52, 0x6e, 0xe5, 0x8a, 0x1e, 0x7f, 0x2a, 0x8b, 0x90, 0x37, - 0x9b, 0xc8, 0xf6, 0x0c, 0xdb, 0x2a, 0x5c, 0x8a, 0xa6, 0xe8, 0xf7, 0xae, 0xa5, 0x1c, 0xc1, 0xa2, - 0x4b, 0x27, 0xa8, 0x56, 0xc3, 0x17, 0x6a, 0x0d, 0x1f, 0x85, 0xb8, 0x30, 0x4a, 0x65, 0xab, 0xaf, - 0x7f, 0x72, 0x5c, 0x1a, 0xf9, 0xe7, 0x71, 0xe9, 0x2b, 0x0d, 0x3b, 0x6c, 0xb6, 0xeb, 0x65, 0x93, - 0xb8, 0x91, 0xaf, 0xd1, 0x7f, 0x6b, 0x81, 0xf5, 0xb8, 0x12, 0x3e, 0x69, 0xe1, 0xa0, 0xbc, 0x83, - 0xcd, 0xcf, 0x3e, 0x5e, 0x83, 0x28, 0x14, 0x3b, 0xd8, 0xd4, 0xaf, 0xbb, 0xb6, 0x27, 0xc1, 0xcc, - 0x0c, 0xa3, 0x4e, 0x1f, 0xc3, 0x63, 0x17, 0x62, 0x18, 0x75, 0x24, 0x86, 0xb5, 0x57, 0x60, 0x75, - 0x78, 0x30, 0x75, 0x1c, 0xb4, 0x88, 0x17, 0x60, 0xed, 0x37, 0x39, 0xb8, 0xba, 0x17, 0x34, 0xee, - 0xd9, 0x1f, 0xb4, 0x6d, 0x6b, 0x9f, 0xa6, 0xc7, 0x80, 0x38, 0x7f, 0x0f, 0x2e, 0x23, 0x97, 0xb4, - 0xbd, 0x90, 0x47, 0xb9, 0x5a, 0x3e, 0x83, 0x03, 0xbb, 0x5e, 0xa8, 0x47, 0xab, 0x95, 0x5b, 0x00, - 0x4d, 0x12, 0x84, 0x86, 0x85, 0x3d, 0xe2, 0xf2, 0x5d, 0xd0, 0xaf, 0xd0, 0x91, 0x1d, 0x3a, 0xa0, - 0x7d, 0x98, 0x83, 0xeb, 0x69, 0x4c, 0x31, 0x5c, 0xe5, 0x11, 0xe4, 0x83, 0xd0, 0x08, 0xc9, 0x63, - 0xec, 0x31, 0x70, 0x93, 0x1b, 0x8b, 0xe5, 0x28, 0x26, 0x34, 0x13, 0xcb, 0x51, 0x26, 0x96, 0x6b, - 0xc4, 0xf6, 0xaa, 0x5f, 0xa7, 0xf0, 0xfe, 0xf4, 0xef, 0xd2, 0xca, 0x29, 0xe0, 0xd1, 0x05, 0x81, - 0x3e, 0x11, 0x84, 0x07, 0x54, 0xb7, 0xf6, 0x87, 0x1c, 0xcc, 0x51, 0x08, 0xfb, 0x7b, 0x2f, 0x36, - 0x32, 0x6b, 0x30, 0xef, 0x04, 0x2e, 0x77, 0xd0, 0xb0, 0xeb, 0x66, 0x2a, 0x44, 0xb3, 0x4e, 0xe0, - 0x32, 0x78, 0xbb, 0x75, 0x93, 0x47, 0xea, 0x2d, 0x58, 0xec, 0x41, 0x29, 0x62, 0xb5, 0x0e, 0x0b, - 0xa1, 0x8f, 0xbc, 0x00, 0x99, 0x2c, 0xf1, 0x4c, 0xe2, 0xb6, 0x1c, 0x1c, 0x62, 0x06, 0x3d, 0xaf, - 0xcf, 0x27, 0xe6, 0x6a, 0xd1, 0x94, 0xf6, 0xc7, 0x1c, 0xcc, 0xec, 0x05, 0x8d, 0x9a, 0x83, 0x91, - 0x5f, 0x45, 0x0e, 0xf2, 0x4c, 0x7c, 0xbe, 0x63, 0xd7, 0x8d, 0xc7, 0xe8, 0x17, 0x8a, 0x07, 0x35, - 0xde, 0x44, 0x9e, 0x87, 0x1d, 0x7e, 0x66, 0xf4, 0xf8, 0x53, 0x5b, 0x84, 0x1b, 0x19, 0xa4, 0x22, - 0xa7, 0xff, 0xcc, 0x73, 0x9a, 0xe6, 0x3d, 0x76, 0x5f, 0xd4, 0xce, 0xdd, 0x04, 0x96, 0xc1, 0xc6, - 0x8f, 0x88, 0x17, 0x15, 0x16, 0x3d, 0x4f, 0x07, 0x1e, 0x12, 0x0f, 0x2b, 0x2a, 0xe4, 0x7d, 0x6c, - 0x62, 0xfb, 0x10, 0xfb, 0x91, 0x1f, 0xe2, 0x5b, 0x2b, 0xb0, 0x64, 0x4f, 0x80, 0x15, 0x7e, 0xfc, - 0x65, 0x1c, 0xe6, 0xd9, 0x54, 0xc3, 0x0e, 0x42, 0xec, 0xbf, 0x19, 0x6b, 0xfb, 0x0e, 0x4c, 0x9b, - 0xc4, 0xf3, 0x30, 0xdf, 0xd7, 0x38, 0xf8, 0xd5, 0xc2, 0xc9, 0x71, 0x69, 0xe1, 0x09, 0x72, 0x9d, - 0x2d, 0x2d, 0x35, 0xad, 0xe9, 0x53, 0xdd, 0xef, 0x5d, 0x4b, 0xd1, 0x60, 0xaa, 0x8e, 0xcd, 0xe6, - 0xe6, 0x46, 0xcb, 0xc7, 0x8f, 0xec, 0x4e, 0x61, 0x8a, 0x01, 0x4a, 0x8d, 0x29, 0xaf, 0xa6, 0x4e, - 0x28, 0x2f, 0x57, 0xd7, 0x4e, 0x8e, 0x4b, 0x73, 0x5c, 0x7f, 0x77, 0x4e, 0x4b, 0x1c, 0x5c, 0x65, - 0x1d, 0xae, 0x74, 0x73, 0x76, 0x9c, 0x2d, 0x5a, 0x38, 0x39, 0x2e, 0xcd, 0xf2, 0x45, 0x62, 0x4a, - 0xd3, 0xf3, 0x76, 0x94, 0xc1, 0xc9, 0x8d, 0xb9, 0x9c, 0xde, 0x98, 0xb7, 0x80, 0xa7, 0xe8, 0x23, - 0xec, 0x1b, 0xd1, 0xa6, 0x53, 0x5f, 0x81, 0xa9, 0x2d, 0x9e, 0x1c, 0x97, 0x54, 0xae, 0x56, 0x22, - 0xa4, 0xe9, 0x73, 0xf1, 0x68, 0x8d, 0x0f, 0xb2, 0x94, 0x9c, 0x6d, 0x7b, 0x75, 0xe2, 0x59, 0xb6, - 0xd7, 0x30, 0x5a, 0xd8, 0xb7, 0x89, 0x55, 0x98, 0x5c, 0xca, 0xad, 0x8c, 0x55, 0x6f, 0x9e, 0x1c, - 0x97, 0x6e, 0x70, 0x65, 0x59, 0x09, 0x4d, 0x9f, 0x11, 0x43, 0x6f, 0xb3, 0x11, 0xc5, 0x81, 0x79, - 0x7a, 0xa3, 0x64, 0x4b, 0xfa, 0xf4, 0x05, 0x94, 0xf4, 0x39, 0xd7, 0xf6, 0x32, 0xd7, 0x08, 0xb5, - 0x86, 0x3a, 0x3d, 0xd6, 0xae, 0x5e, 0x88, 0x35, 0xd4, 0xc9, 0x58, 0xfb, 0x26, 0x14, 0x68, 0xf9, - 0x71, 0x58, 0x35, 0x31, 0x18, 0x5b, 0x30, 0xb0, 0x87, 0xea, 0x0e, 0xb6, 0x0a, 0x33, 0xac, 0x6c, - 0x5c, 0x73, 0x02, 0x37, 0x51, 0x6c, 0xde, 0xe0, 0x93, 0x5b, 0xf9, 0x9f, 0x7d, 0x54, 0x1a, 0xf9, - 0xef, 0x47, 0xa5, 0x11, 0xed, 0x16, 0xdc, 0x94, 0xe4, 0xac, 0xc8, 0xe9, 0x5f, 0xe5, 0x58, 0xc9, - 0xaa, 0x39, 0xc8, 0x76, 0xdf, 0xf1, 0x2c, 0xec, 0xe0, 0x06, 0x0a, 0xb1, 0xc5, 0xca, 0xda, 0xa0, - 0x2b, 0x7e, 0x09, 0xa6, 0xc4, 0xf1, 0xea, 0xd6, 0x1b, 0x88, 0x4f, 0xd8, 0xae, 0xa5, 0x2c, 0xc0, - 0x38, 0x6e, 0x11, 0xb3, 0xc9, 0x0e, 0xdf, 0x98, 0xce, 0x3f, 0x52, 0x27, 0x6f, 0x3c, 0x7d, 0xf2, - 0x7e, 0x30, 0x96, 0x1f, 0x9b, 0x1d, 0xd7, 0x96, 0xe1, 0x76, 0x5f, 0x40, 0x02, 0x76, 0x18, 0x1d, - 0xd2, 0x3a, 0x2f, 0x35, 0xef, 0xc6, 0xf4, 0x69, 0x10, 0xe4, 0x54, 0x45, 0xb8, 0x94, 0xa9, 0x08, - 0xcb, 0x30, 0xed, 0xb5, 0x5d, 0xc3, 0x8f, 0x35, 0x46, 0xa8, 0xa7, 0xbc, 0xb6, 0x2b, 0xac, 0x68, - 0x4b, 0x50, 0x94, 0x5b, 0x15, 0xb8, 0x7e, 0x9a, 0x83, 0xd9, 0xbd, 0xa0, 0xb1, 0x6d, 0x59, 0x5f, - 0x1c, 0xd2, 0x16, 0x80, 0xa0, 0x85, 0x41, 0x61, 0x74, 0x69, 0x74, 0x65, 0x72, 0x43, 0x2d, 0x67, - 0xa8, 0x64, 0x59, 0xd8, 0xd1, 0x13, 0xd2, 0x9a, 0x0a, 0x85, 0x2c, 0x0c, 0x81, 0xf1, 0x3d, 0x98, - 0x11, 0xa3, 0x0f, 0xb0, 0xdd, 0x68, 0x86, 0xca, 0x06, 0x4c, 0x20, 0xcb, 0xf2, 0x71, 0x10, 0x70, - 0x84, 0xd5, 0xc2, 0x67, 0x1f, 0xaf, 0x2d, 0x44, 0xb9, 0xb9, 0xcd, 0x67, 0xf6, 0x43, 0xdf, 0xf6, - 0x1a, 0x7a, 0x2c, 0xa8, 0x5c, 0x87, 0xcb, 0x47, 0x6c, 0x35, 0x03, 0x3e, 0xa6, 0x47, 0x5f, 0xda, - 0xef, 0xa3, 0x8c, 0x6a, 0x22, 0xaf, 0x81, 0x33, 0x86, 0xce, 0x1d, 0x8b, 0x3d, 0x98, 0x13, 0xde, - 0x19, 0xdc, 0x50, 0x1c, 0x92, 0xa5, 0xfe, 0x21, 0xe1, 0x46, 0xf5, 0xd9, 0xc3, 0x0c, 0x8a, 0x38, - 0xc7, 0xa4, 0x10, 0x45, 0x9c, 0x3e, 0xcc, 0x81, 0xb2, 0x17, 0x34, 0x76, 0x30, 0xbd, 0x8a, 0x85, - 0xd4, 0x79, 0x3d, 0xd8, 0x84, 0xfc, 0x21, 0x72, 0x0c, 0x1a, 0xbd, 0xe8, 0x0e, 0x1e, 0x10, 0xe3, - 0x43, 0xe4, 0xd0, 0x11, 0xed, 0x25, 0x50, 0x7b, 0x11, 0x08, 0x80, 0xbf, 0xcb, 0x45, 0x67, 0x3b, - 0x08, 0x89, 0x8f, 0x77, 0xbd, 0x10, 0xfb, 0xec, 0xbe, 0xdf, 0x36, 0x4d, 0x71, 0x59, 0x9f, 0x99, - 0x29, 0x2c, 0x67, 0x2f, 0x33, 0x7e, 0x77, 0xa6, 0xaf, 0xac, 0x65, 0x98, 0x46, 0xdc, 0x88, 0x41, - 0x8e, 0x3c, 0x71, 0x89, 0x4e, 0x45, 0x83, 0xf7, 0xe9, 0x98, 0xf6, 0x32, 0x2c, 0x0f, 0x40, 0x27, - 0xbc, 0xf8, 0x00, 0x96, 0x04, 0x3f, 0x16, 0x3e, 0xee, 0x37, 0x91, 0x8f, 0x83, 0x37, 0x3a, 0x66, - 0x93, 0xd5, 0xc1, 0x73, 0x79, 0x52, 0x00, 0x1a, 0x47, 0xd2, 0xc2, 0x51, 0xc0, 0xf5, 0xf8, 0x53, - 0x5b, 0x85, 0x95, 0x61, 0x26, 0x05, 0xbc, 0x06, 0xab, 0x34, 0x35, 0xe4, 0xd8, 0x75, 0x5a, 0xe9, - 0x77, 0x78, 0x41, 0xb2, 0x89, 0x77, 0xd1, 0xa0, 0x78, 0x71, 0x91, 0x18, 0x12, 0x50, 0xde, 0x64, - 0x1c, 0x58, 0xc7, 0x41, 0xdb, 0xc5, 0x82, 0x7c, 0x9c, 0x07, 0x85, 0x76, 0x93, 0x1d, 0xd1, 0xb4, - 0x26, 0x61, 0xe6, 0x17, 0x79, 0x46, 0x73, 0x6a, 0x54, 0x0d, 0x3e, 0xf0, 0x91, 0x85, 0x75, 0xd2, - 0x0e, 0xb1, 0xf2, 0x0d, 0xb8, 0x82, 0xda, 0x61, 0x93, 0xf8, 0x76, 0xf8, 0x64, 0x68, 0x99, 0xe8, - 0x8a, 0x2a, 0x1a, 0x4c, 0xb3, 0x63, 0x91, 0x01, 0x33, 0x49, 0x07, 0x6b, 0x51, 0x58, 0xaa, 0x50, - 0xe4, 0xa7, 0xd8, 0x08, 0x89, 0xe1, 0xe3, 0x23, 0xe4, 0x5b, 0x86, 0x2c, 0x0d, 0x55, 0x2e, 0x75, - 0x40, 0x74, 0x26, 0x53, 0x4b, 0x26, 0xe5, 0x77, 0xe1, 0x56, 0x57, 0x47, 0x48, 0x71, 0x67, 0x54, - 0xf0, 0x24, 0x5d, 0x8c, 0x55, 0x30, 0xd7, 0x52, 0x1a, 0x76, 0x81, 0x33, 0xa9, 0x2e, 0x06, 0x19, - 0xe3, 0xe1, 0xd7, 0xd6, 0x2d, 0x2a, 0x19, 0xe3, 0x38, 0xe8, 0x61, 0x37, 0x3f, 0x84, 0xe5, 0x58, - 0x45, 0x0c, 0x46, 0xa6, 0x8b, 0x73, 0xac, 0x22, 0x17, 0x8d, 0x20, 0xf5, 0x2a, 0xfb, 0x3e, 0xdc, - 0x8e, 0x54, 0x10, 0x83, 0x03, 0x94, 0xa8, 0x9a, 0x60, 0xaa, 0x5e, 0x62, 0x82, 0x07, 0x84, 0xee, - 0x6a, 0xaf, 0xa2, 0x0a, 0x2c, 0x44, 0xa8, 0x18, 0xf1, 0x33, 0x88, 0xc7, 0xf4, 0x15, 0xf2, 0x6c, - 0xed, 0x1c, 0x9f, 0x63, 0x44, 0xf0, 0xbe, 0x47, 0x35, 0x28, 0x9b, 0x70, 0x3d, 0xbb, 0x80, 0x7f, - 0x17, 0xae, 0xb0, 0x25, 0xf3, 0xa9, 0x25, 0x3c, 0x18, 0xca, 0x3a, 0x5c, 0xcb, 0x2e, 0x62, 0xa8, - 0x38, 0x57, 0xd4, 0x95, 0xd4, 0x1a, 0xe6, 0x32, 0xed, 0xb3, 0xba, 0x1c, 0xb6, 0xbb, 0x60, 0x92, - 0xf7, 0x59, 0x82, 0xd1, 0xc6, 0xe2, 0x77, 0x41, 0x49, 0x8b, 0x33, 0x2f, 0x38, 0x71, 0x9e, 0x49, - 0x48, 0x33, 0x1f, 0x6e, 0xc0, 0x44, 0x8b, 0x10, 0x16, 0xa3, 0x69, 0x7e, 0x53, 0xd1, 0xcf, 0x5d, - 0x4b, 0xd9, 0x02, 0x95, 0x72, 0x39, 0xe4, 0x38, 0xe4, 0x08, 0x5b, 0x46, 0x70, 0x84, 0x5a, 0x86, - 0x43, 0x82, 0x20, 0x41, 0xe9, 0x58, 0x57, 0xbf, 0xcd, 0x05, 0xf6, 0x8f, 0x50, 0xeb, 0x1e, 0x09, - 0x02, 0x56, 0x91, 0xde, 0x85, 0x19, 0xca, 0x3a, 0xd9, 0x9a, 0xa8, 0x5f, 0x99, 0x39, 0x57, 0xbf, - 0x32, 0xed, 0xda, 0x1e, 0xd5, 0xbc, 0xcd, 0xdb, 0x16, 0xaa, 0x17, 0x75, 0x52, 0x7a, 0x67, 0xcf, - 0xa9, 0x17, 0x75, 0xba, 0x7a, 0xb7, 0xbe, 0xf5, 0x93, 0xcf, 0x9f, 0xae, 0x76, 0x0f, 0xe5, 0xcf, - 0x3f, 0x7f, 0xba, 0xfa, 0x72, 0xf4, 0x08, 0xd5, 0xe9, 0x3e, 0x43, 0x49, 0x8e, 0x7d, 0x44, 0x20, - 0xb3, 0xc3, 0xa2, 0x5a, 0xfc, 0x35, 0xc7, 0xaa, 0x05, 0xbf, 0xa3, 0x2e, 0xa0, 0x5a, 0xdc, 0x86, - 0xa9, 0x64, 0xf2, 0xc4, 0xc5, 0x22, 0x91, 0x33, 0x43, 0x9e, 0x2b, 0x4e, 0xef, 0x6a, 0x16, 0x73, - 0xe4, 0x6a, 0x76, 0x58, 0xb8, 0xfa, 0xf7, 0x51, 0xe6, 0x2a, 0xbf, 0x37, 0xbe, 0x0c, 0xae, 0x26, - 0x53, 0x7b, 0xec, 0x0c, 0xa9, 0x3d, 0x7e, 0xd6, 0xd4, 0xbe, 0xfc, 0x7f, 0x4a, 0xed, 0x89, 0x17, - 0x9a, 0xda, 0xd9, 0x8d, 0x8b, 0xf6, 0x3b, 0x3b, 0x2c, 0xf6, 0xfb, 0x5f, 0x97, 0xd8, 0x35, 0xb9, - 0x8f, 0xc3, 0x1a, 0x71, 0xdd, 0xb6, 0x67, 0x87, 0x4f, 0xde, 0x26, 0xc4, 0xa1, 0xfc, 0x3f, 0xc4, - 0x94, 0x33, 0xa7, 0x2e, 0xde, 0x41, 0x7c, 0xee, 0x14, 0xc4, 0xe0, 0x3e, 0x4c, 0xfa, 0x4c, 0x71, - 0xf2, 0x29, 0xb4, 0x7c, 0xb6, 0x86, 0x52, 0x07, 0xae, 0x82, 0x6d, 0xe3, 0xfb, 0xb0, 0x90, 0xec, - 0x1b, 0xad, 0x38, 0xe6, 0x63, 0xe7, 0x8a, 0xb9, 0xe2, 0x74, 0x9b, 0x4c, 0x2b, 0x0a, 0xfc, 0xeb, - 0x34, 0xf0, 0xb1, 0x6f, 0x34, 0xec, 0x77, 0xa5, 0x61, 0x97, 0xc7, 0x2f, 0xe2, 0xe0, 0xf2, 0xc9, - 0x78, 0x0b, 0x36, 0x9e, 0xce, 0xc2, 0xe8, 0x5e, 0xd0, 0x50, 0x1e, 0xc0, 0x64, 0xf2, 0xe1, 0xaf, - 0xd4, 0xc3, 0xf9, 0xd3, 0xef, 0x93, 0xea, 0x57, 0x87, 0x08, 0x88, 0x47, 0xb9, 0xf7, 0xe1, 0x6a, - 0xe6, 0x51, 0x51, 0x93, 0x2e, 0x4d, 0xc9, 0xa8, 0xab, 0xc3, 0x65, 0x84, 0x85, 0x07, 0x30, 0x99, - 0x7c, 0xf9, 0x92, 0x42, 0x4f, 0x08, 0xc8, 0xa1, 0x4b, 0x9e, 0xa3, 0x94, 0x47, 0x30, 0xdb, 0xf3, - 0x14, 0x75, 0x47, 0xbe, 0x38, 0x2d, 0xa5, 0xbe, 0x72, 0x1a, 0x29, 0x61, 0xa7, 0x03, 0xd7, 0xfb, - 0x3c, 0x0f, 0x48, 0xc3, 0x20, 0x97, 0x55, 0x37, 0x4e, 0x2f, 0x2b, 0x2c, 0x13, 0x98, 0x97, 0xb5, - 0xf8, 0x7d, 0x22, 0xd4, 0x23, 0xa8, 0x56, 0x4e, 0x29, 0x28, 0x0c, 0xbe, 0x07, 0xd3, 0xe9, 0xd6, - 0xfd, 0xb6, 0x4c, 0x43, 0x4a, 0x44, 0xfd, 0xda, 0x50, 0x11, 0xa1, 0xfe, 0x08, 0xae, 0x49, 0x7b, - 0xce, 0x3e, 0x81, 0x94, 0xb6, 0xa7, 0x7d, 0x02, 0x39, 0xb0, 0x95, 0x55, 0x4c, 0x98, 0xc9, 0xb6, - 0xb1, 0xcb, 0x32, 0x35, 0x19, 0x21, 0xf5, 0xee, 0x29, 0x84, 0x84, 0x91, 0x1f, 0x43, 0xa1, 0x6f, - 0x2b, 0xda, 0x27, 0xe3, 0xe4, 0xd2, 0xea, 0xab, 0x67, 0x91, 0x16, 0xf6, 0x7f, 0x99, 0x83, 0x5b, - 0x83, 0xdb, 0xc8, 0x75, 0x99, 0xde, 0x81, 0x4b, 0xd4, 0xd7, 0xce, 0xbc, 0x24, 0x99, 0xbd, 0xb2, - 0xb6, 0x51, 0x9a, 0xbd, 0x12, 0x41, 0x79, 0xf6, 0x0e, 0xe8, 0x0f, 0x95, 0x87, 0x30, 0x95, 0xfa, - 0xa5, 0x60, 0x49, 0x7e, 0xe4, 0xba, 0x12, 0xea, 0xca, 0x30, 0x09, 0xa1, 0xfb, 0xb7, 0x39, 0x28, - 0x0d, 0xfb, 0x41, 0x70, 0xb3, 0x7f, 0xac, 0xfa, 0x2e, 0x52, 0xbf, 0x7d, 0x8e, 0x45, 0xc9, 0xea, - 0x9d, 0x69, 0x87, 0xb5, 0x3e, 0xa9, 0x93, 0x90, 0x91, 0x57, 0x6f, 0x79, 0x33, 0x4c, 0x8b, 0x6c, - 0x4f, 0x23, 0x2c, 0x2d, 0xb2, 0x59, 0x29, 0x79, 0x91, 0xed, 0x47, 0xa3, 0xa9, 0x9d, 0x1e, 0x0a, - 0x7d, 0xa7, 0xff, 0xe9, 0x1b, 0x66, 0xa7, 0x1f, 0x87, 0xa5, 0x76, 0x7a, 0xf8, 0xeb, 0x9d, 0xfe, - 0x5b, 0x30, 0xcc, 0x4e, 0x3f, 0xee, 0x44, 0x2f, 0x8d, 0x3e, 0xbc, 0x49, 0x1a, 0x7d, 0xb9, 0xac, - 0xbc, 0xd6, 0x0d, 0xa6, 0x0c, 0xd5, 0x7b, 0x9f, 0x3c, 0x2b, 0xe6, 0x3e, 0x7d, 0x56, 0xcc, 0xfd, - 0xe7, 0x59, 0x31, 0xf7, 0xeb, 0xe7, 0xc5, 0x91, 0x4f, 0x9f, 0x17, 0x47, 0xfe, 0xf1, 0xbc, 0x38, - 0xf2, 0x70, 0x23, 0xc1, 0x75, 0xf6, 0x99, 0xde, 0xb5, 0x7b, 0xa8, 0x1e, 0x54, 0x22, 0xd6, 0x72, - 0xb8, 0xfe, 0x5a, 0x92, 0xb9, 0x30, 0xee, 0x53, 0xbf, 0xcc, 0x7e, 0x12, 0xdf, 0xfc, 0x5f, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x31, 0x04, 0xe4, 0xe0, 0xdd, 0x1f, 0x00, 0x00, + // 2300 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0x5f, 0x6f, 0x1b, 0xc7, + 0x11, 0x17, 0xad, 0x7f, 0xd4, 0x48, 0xb2, 0xa8, 0x93, 0x64, 0x53, 0xe7, 0x98, 0x94, 0x4f, 0x4e, + 0xaa, 0xca, 0x31, 0x59, 0xc9, 0x41, 0xdb, 0x28, 0x29, 0x50, 0x49, 0x76, 0x13, 0x35, 0x96, 0x6d, + 0x9c, 0x14, 0x1b, 0x30, 0x10, 0x5c, 0x96, 0x77, 0x6b, 0xf2, 0xe0, 0xbb, 0x5b, 0xe6, 0xee, 0x28, + 0xd1, 0x79, 0x28, 0x82, 0x02, 0x05, 0x8a, 0xa2, 0x45, 0x5b, 0x14, 0x7d, 0xeb, 0x43, 0x0a, 0x14, + 0x68, 0xd1, 0xbe, 0x04, 0x45, 0x3e, 0x44, 0x8a, 0x02, 0x45, 0x90, 0xa7, 0xa2, 0x05, 0xd4, 0xc2, + 0x7e, 0x48, 0x9f, 0xfd, 0x09, 0x8a, 0xdd, 0xbd, 0x5b, 0xde, 0x1d, 0x97, 0xa4, 0xa4, 0xa8, 0x46, + 0x5f, 0x44, 0xee, 0xee, 0xec, 0xcc, 0x6f, 0x66, 0x67, 0x67, 0x67, 0x86, 0x82, 0x62, 0x10, 0xfa, + 0xb6, 0x85, 0xab, 0x41, 0x88, 0x1e, 0x63, 0xbb, 0x66, 0x56, 0xc3, 0x76, 0xa5, 0xe9, 0x93, 0x90, + 0x28, 0x33, 0x7c, 0xa5, 0x12, 0xaf, 0xa8, 0xe5, 0x2c, 0xe9, 0x01, 0x72, 0x6c, 0x0b, 0x85, 0xc4, + 0xe7, 0x3b, 0xd4, 0xf9, 0x3a, 0xa9, 0x13, 0xf6, 0xb5, 0x4a, 0xbf, 0x45, 0xb3, 0x8b, 0x26, 0x09, + 0x5c, 0x12, 0x18, 0x7c, 0x81, 0x0f, 0xa2, 0xa5, 0x12, 0x1f, 0x55, 0x6b, 0x28, 0xc0, 0xd5, 0x83, + 0xb5, 0x1a, 0x0e, 0xd1, 0x5a, 0xd5, 0x24, 0xb6, 0x17, 0xad, 0x5f, 0x8c, 0xd6, 0xdd, 0xa0, 0x5e, + 0x3d, 0x58, 0xa3, 0x1f, 0xd1, 0xc2, 0x2c, 0x72, 0x6d, 0x8f, 0x54, 0xd9, 0x5f, 0x3e, 0xa5, 0xfd, + 0xf5, 0x1c, 0x68, 0xbb, 0x41, 0xfd, 0xdd, 0xa6, 0x85, 0x42, 0xbc, 0xe3, 0x79, 0xd8, 0xd7, 0xb1, + 0x85, 0xdd, 0x66, 0x68, 0x13, 0x4f, 0x47, 0x21, 0xde, 0x22, 0x2d, 0xcf, 0x0a, 0x94, 0x22, 0x8c, + 0x9b, 0x3e, 0xa6, 0xa0, 0x8b, 0xb9, 0xa5, 0xdc, 0xca, 0x84, 0x1e, 0x0f, 0x95, 0x45, 0xc8, 0x9b, + 0x0d, 0x64, 0x7b, 0x86, 0x6d, 0x15, 0xcf, 0x45, 0x4b, 0x74, 0xbc, 0x63, 0x29, 0x87, 0xb0, 0xe8, + 0xd2, 0x05, 0xca, 0xd5, 0xf0, 0x05, 0x5b, 0xc3, 0x47, 0x21, 0x2e, 0x0e, 0x53, 0xda, 0xad, 0x37, + 0x3f, 0x3b, 0x2a, 0x0f, 0xfd, 0xe3, 0xa8, 0xfc, 0x4a, 0xdd, 0x0e, 0x1b, 0xad, 0x5a, 0xc5, 0x24, + 0x6e, 0xa4, 0x6b, 0xf4, 0x71, 0x3d, 0xb0, 0x1e, 0x57, 0xc3, 0x27, 0x4d, 0x1c, 0x54, 0x6e, 0x62, + 0xf3, 0x8b, 0x4f, 0xaf, 0x43, 0x64, 0x8a, 0x9b, 0xd8, 0xd4, 0x2f, 0xb8, 0xb6, 0x27, 0xc1, 0xcc, + 0x04, 0xa3, 0x76, 0x0f, 0xc1, 0x23, 0x67, 0x22, 0x18, 0xb5, 0x25, 0x82, 0xb5, 0x57, 0x61, 0x75, + 0xb0, 0x31, 0x75, 0x1c, 0x34, 0x89, 0x17, 0x60, 0xed, 0x97, 0x39, 0x38, 0xbf, 0x1b, 0xd4, 0x6f, + 0xdb, 0x1f, 0xb4, 0x6c, 0x6b, 0x8f, 0xba, 0x47, 0x1f, 0x3b, 0x7f, 0x0f, 0xc6, 0x90, 0x4b, 0x5a, + 0x5e, 0xc8, 0xad, 0xbc, 0x55, 0x39, 0x81, 0x02, 0x3b, 0x5e, 0xa8, 0x47, 0xbb, 0x95, 0xcb, 0x00, + 0x0d, 0x12, 0x84, 0x86, 0x85, 0x3d, 0xe2, 0xf2, 0x53, 0xd0, 0x27, 0xe8, 0xcc, 0x4d, 0x3a, 0xa1, + 0x7d, 0x94, 0x83, 0x0b, 0x69, 0x4c, 0x31, 0x5c, 0xe5, 0x11, 0xe4, 0x83, 0xd0, 0x08, 0xc9, 0x63, + 0xec, 0x31, 0x70, 0x93, 0xeb, 0x8b, 0x95, 0xc8, 0x26, 0xd4, 0x13, 0x2b, 0x91, 0x27, 0x56, 0xb6, + 0x89, 0xed, 0x6d, 0x7d, 0x83, 0xc2, 0xfb, 0xe3, 0xbf, 0xca, 0x2b, 0xc7, 0x80, 0x47, 0x37, 0x04, + 0xfa, 0x78, 0x10, 0xee, 0x53, 0xde, 0xda, 0xef, 0x72, 0x30, 0x4b, 0x21, 0xec, 0xed, 0xbe, 0x58, + 0xcb, 0x5c, 0x87, 0x39, 0x27, 0x70, 0xb9, 0x82, 0x86, 0x5d, 0x33, 0x53, 0x26, 0x2a, 0x38, 0x81, + 0xcb, 0xe0, 0xed, 0xd4, 0x4c, 0x6e, 0xa9, 0x3b, 0xb0, 0xd8, 0x85, 0x52, 0xd8, 0x6a, 0x0d, 0xe6, + 0x43, 0x1f, 0x79, 0x01, 0x32, 0x99, 0xe3, 0x99, 0xc4, 0x6d, 0x3a, 0x38, 0xc4, 0x0c, 0x7a, 0x5e, + 0x9f, 0x4b, 0xac, 0x6d, 0x47, 0x4b, 0xda, 0x1f, 0x72, 0x30, 0xb3, 0x1b, 0xd4, 0xb7, 0x1d, 0x8c, + 0xfc, 0x2d, 0xe4, 0x20, 0xcf, 0xc4, 0xa7, 0xbb, 0x76, 0x1d, 0x7b, 0x0c, 0x7f, 0x25, 0x7b, 0x50, + 0xe1, 0x0d, 0xe4, 0x79, 0xd8, 0xe1, 0x77, 0x46, 0x8f, 0x87, 0xda, 0x22, 0x5c, 0xcc, 0x20, 0x15, + 0x3e, 0xfd, 0x27, 0xee, 0xd3, 0xd4, 0xef, 0xb1, 0xfb, 0xa2, 0x4e, 0xee, 0x12, 0x30, 0x0f, 0x36, + 0x3e, 0x24, 0x5e, 0x14, 0x58, 0xf4, 0x3c, 0x9d, 0x78, 0x48, 0x3c, 0xac, 0xa8, 0x90, 0xf7, 0xb1, + 0x89, 0xed, 0x03, 0xec, 0x47, 0x7a, 0x88, 0xb1, 0x56, 0x64, 0xce, 0x9e, 0x00, 0x2b, 0xf4, 0xf8, + 0xf3, 0x28, 0xcc, 0xb1, 0xa5, 0xba, 0x1d, 0x84, 0xd8, 0x7f, 0x3b, 0xe6, 0xf6, 0x1d, 0x98, 0x36, + 0x89, 0xe7, 0x61, 0x7e, 0xae, 0xb1, 0xf1, 0xb7, 0x8a, 0xcf, 0x8f, 0xca, 0xf3, 0x4f, 0x90, 0xeb, + 0x6c, 0x68, 0xa9, 0x65, 0x4d, 0x9f, 0xea, 0x8c, 0x77, 0x2c, 0x45, 0x83, 0xa9, 0x1a, 0x36, 0x1b, + 0x37, 0xd6, 0x9b, 0x3e, 0x7e, 0x64, 0xb7, 0x8b, 0x53, 0x0c, 0x50, 0x6a, 0x4e, 0x79, 0x2d, 0x75, + 0x43, 0x79, 0xb8, 0x5a, 0x78, 0x7e, 0x54, 0x9e, 0xe5, 0xfc, 0x3b, 0x6b, 0x5a, 0xe2, 0xe2, 0x2a, + 0x6b, 0x30, 0xd1, 0xf1, 0xd9, 0x51, 0xb6, 0x69, 0xfe, 0xf9, 0x51, 0xb9, 0xc0, 0x37, 0x89, 0x25, + 0x4d, 0xcf, 0xdb, 0x91, 0x07, 0x27, 0x0f, 0x66, 0x2c, 0x7d, 0x30, 0x77, 0x80, 0xbb, 0xe8, 0x23, + 0xec, 0x1b, 0xd1, 0xa1, 0x53, 0x5d, 0x81, 0xb1, 0x2d, 0x3d, 0x3f, 0x2a, 0xab, 0x9c, 0xad, 0x84, + 0x48, 0xd3, 0x67, 0xe3, 0xd9, 0x6d, 0x3e, 0xc9, 0x5c, 0xb2, 0xd0, 0xf2, 0x6a, 0xc4, 0xb3, 0x6c, + 0xaf, 0x6e, 0x34, 0xb1, 0x6f, 0x13, 0xab, 0x38, 0xb9, 0x94, 0x5b, 0x19, 0xd9, 0xba, 0xf4, 0xfc, + 0xa8, 0x7c, 0x91, 0x33, 0xcb, 0x52, 0x68, 0xfa, 0x8c, 0x98, 0xba, 0xc7, 0x66, 0x14, 0x07, 0xe6, + 0xe8, 0x8b, 0x92, 0x0d, 0xe9, 0xd3, 0x67, 0x10, 0xd2, 0x67, 0x5d, 0xdb, 0xcb, 0x3c, 0x23, 0x54, + 0x1a, 0x6a, 0x77, 0x49, 0x3b, 0x7f, 0x26, 0xd2, 0x50, 0x3b, 0x23, 0xed, 0x5b, 0x50, 0xa4, 0xe1, + 0xc7, 0x61, 0xd1, 0xc4, 0x60, 0xd9, 0x82, 0x81, 0x3d, 0x54, 0x73, 0xb0, 0x55, 0x9c, 0x61, 0x61, + 0x63, 0xc1, 0x09, 0xdc, 0x44, 0xb0, 0xb9, 0xc5, 0x17, 0x37, 0xf2, 0x3f, 0xfe, 0xb8, 0x3c, 0xf4, + 0x9f, 0x8f, 0xcb, 0x43, 0xda, 0x65, 0xb8, 0x24, 0xf1, 0x59, 0xe1, 0xd3, 0x3f, 0xcf, 0xb1, 0x90, + 0xb5, 0xed, 0x20, 0xdb, 0x7d, 0xd7, 0xb3, 0xb0, 0x83, 0xeb, 0x28, 0xc4, 0x16, 0x0b, 0x6b, 0xfd, + 0x9e, 0xf8, 0x25, 0x98, 0x12, 0xd7, 0xab, 0x13, 0x6f, 0x20, 0xbe, 0x61, 0x3b, 0x96, 0x32, 0x0f, + 0xa3, 0xb8, 0x49, 0xcc, 0x06, 0xbb, 0x7c, 0x23, 0x3a, 0x1f, 0xa4, 0x6e, 0xde, 0x68, 0xfa, 0xe6, + 0x7d, 0x7f, 0x24, 0x3f, 0x52, 0x18, 0xd5, 0x96, 0xe1, 0x4a, 0x4f, 0x40, 0x02, 0x76, 0x18, 0x5d, + 0xd2, 0x1a, 0x0f, 0x35, 0xf7, 0xe3, 0xf4, 0xa9, 0x1f, 0xe4, 0x54, 0x44, 0x38, 0x97, 0x89, 0x08, + 0xcb, 0x30, 0xed, 0xb5, 0x5c, 0xc3, 0x8f, 0x39, 0x46, 0xa8, 0xa7, 0xbc, 0x96, 0x2b, 0xa4, 0x68, + 0x4b, 0x50, 0x92, 0x4b, 0x15, 0xb8, 0x7e, 0x94, 0x83, 0xc2, 0x6e, 0x50, 0xdf, 0xb4, 0xac, 0xaf, + 0x0e, 0x69, 0x03, 0x40, 0xa4, 0x85, 0x41, 0x71, 0x78, 0x69, 0x78, 0x65, 0x72, 0x5d, 0xad, 0x64, + 0x52, 0xc9, 0x8a, 0x90, 0xa3, 0x27, 0xa8, 0x35, 0x15, 0x8a, 0x59, 0x18, 0x02, 0xe3, 0x7b, 0x30, + 0x23, 0x66, 0x1f, 0x60, 0xbb, 0xde, 0x08, 0x95, 0x75, 0x18, 0x47, 0x96, 0xe5, 0xe3, 0x20, 0xe0, + 0x08, 0xb7, 0x8a, 0x5f, 0x7c, 0x7a, 0x7d, 0x3e, 0xf2, 0xcd, 0x4d, 0xbe, 0xb2, 0x17, 0xfa, 0xb6, + 0x57, 0xd7, 0x63, 0x42, 0xe5, 0x02, 0x8c, 0x1d, 0xb2, 0xdd, 0x0c, 0xf8, 0x88, 0x1e, 0x8d, 0xb4, + 0xdf, 0x46, 0x1e, 0xd5, 0x40, 0x5e, 0x1d, 0x67, 0x04, 0x9d, 0xda, 0x16, 0xbb, 0x30, 0x2b, 0xb4, + 0x33, 0xb8, 0xa0, 0xd8, 0x24, 0x4b, 0xbd, 0x4d, 0xc2, 0x85, 0xea, 0x85, 0x83, 0x0c, 0x8a, 0xd8, + 0xc7, 0xa4, 0x10, 0x85, 0x9d, 0x3e, 0xca, 0x81, 0xb2, 0x1b, 0xd4, 0x6f, 0x62, 0xfa, 0x14, 0x0b, + 0xaa, 0xd3, 0x6a, 0x70, 0x03, 0xf2, 0x07, 0xc8, 0x31, 0xa8, 0xf5, 0xa2, 0x37, 0xb8, 0x8f, 0x8d, + 0x0f, 0x90, 0x43, 0x67, 0xb4, 0x97, 0x40, 0xed, 0x46, 0x20, 0x00, 0xfe, 0x26, 0x17, 0xdd, 0xed, + 0x20, 0x24, 0x3e, 0xde, 0xf1, 0x42, 0xec, 0xb3, 0xf7, 0x7e, 0xd3, 0x34, 0xc5, 0x63, 0x7d, 0xe2, + 0x4c, 0x61, 0x39, 0xfb, 0x98, 0xf1, 0xb7, 0x33, 0xfd, 0x64, 0x2d, 0xc3, 0x34, 0xe2, 0x42, 0x0c, + 0x72, 0xe8, 0x89, 0x47, 0x74, 0x2a, 0x9a, 0xbc, 0x4b, 0xe7, 0xb4, 0x97, 0x61, 0xb9, 0x0f, 0x3a, + 0xa1, 0xc5, 0x07, 0xb0, 0x24, 0xf2, 0x63, 0xa1, 0xe3, 0x5e, 0x03, 0xf9, 0x38, 0xb8, 0xd5, 0x36, + 0x1b, 0x2c, 0x0e, 0x9e, 0x4a, 0x93, 0x22, 0x50, 0x3b, 0x92, 0x26, 0x8e, 0x0c, 0xae, 0xc7, 0x43, + 0x6d, 0x15, 0x56, 0x06, 0x89, 0x14, 0xf0, 0xea, 0x2c, 0xd2, 0x6c, 0x23, 0xc7, 0xae, 0xd1, 0x48, + 0x7f, 0x93, 0x07, 0x24, 0x9b, 0x78, 0x67, 0x0d, 0x8a, 0x07, 0x17, 0x89, 0x20, 0x01, 0xe5, 0x6d, + 0x96, 0x03, 0xeb, 0x38, 0x68, 0xb9, 0x58, 0x24, 0x1f, 0xa7, 0x41, 0xa1, 0x5d, 0x62, 0x57, 0x34, + 0xcd, 0x49, 0x88, 0xf9, 0x69, 0x9e, 0xa5, 0x39, 0xdb, 0x94, 0x0d, 0xde, 0xf7, 0x91, 0x85, 0x75, + 0xd2, 0x0a, 0xb1, 0xf2, 0x4d, 0x98, 0x40, 0xad, 0xb0, 0x41, 0x7c, 0x3b, 0x7c, 0x32, 0x30, 0x4c, + 0x74, 0x48, 0x15, 0x0d, 0xa6, 0xd9, 0xb5, 0xc8, 0x80, 0x99, 0xa4, 0x93, 0xdb, 0x91, 0x59, 0xb6, + 0xa0, 0xc4, 0x6f, 0xb1, 0x11, 0x12, 0xc3, 0xc7, 0x87, 0xc8, 0xb7, 0x0c, 0x99, 0x1b, 0xaa, 0x9c, + 0x6a, 0x9f, 0xe8, 0x8c, 0x66, 0x3b, 0xe9, 0x94, 0xdf, 0x85, 0xcb, 0x1d, 0x1e, 0x21, 0xc5, 0x9d, + 0x61, 0xc1, 0x9d, 0x74, 0x31, 0x66, 0xc1, 0x54, 0x4b, 0x71, 0xd8, 0x01, 0x9e, 0x49, 0x75, 0x30, + 0xc8, 0x32, 0x1e, 0xfe, 0x6c, 0x5d, 0xa6, 0x94, 0x31, 0x8e, 0xfd, 0xae, 0xec, 0xe6, 0x1d, 0x58, + 0x8e, 0x59, 0xc4, 0x60, 0x64, 0xbc, 0x78, 0x8e, 0x55, 0xe2, 0xa4, 0x11, 0xa4, 0x6e, 0x66, 0x6f, + 0xc1, 0x95, 0x88, 0x05, 0x31, 0x38, 0x40, 0x09, 0xab, 0x71, 0xc6, 0xea, 0x25, 0x46, 0xb8, 0x4f, + 0xe8, 0xa9, 0x76, 0x33, 0xaa, 0xc2, 0x7c, 0x84, 0x8a, 0x25, 0x7e, 0x06, 0xf1, 0x18, 0xbf, 0x62, + 0x9e, 0xed, 0x9d, 0xe5, 0x6b, 0x2c, 0x11, 0xbc, 0xeb, 0x51, 0x0e, 0xca, 0x0d, 0xb8, 0x90, 0xdd, + 0xc0, 0xc7, 0xc5, 0x09, 0xb6, 0x65, 0x2e, 0xb5, 0x85, 0x1b, 0x43, 0x59, 0x83, 0x85, 0xec, 0x26, + 0x86, 0x8a, 0xe7, 0x8a, 0xba, 0x92, 0xda, 0xc3, 0x54, 0xa6, 0x75, 0x56, 0x27, 0x87, 0xed, 0x6c, + 0x98, 0xe4, 0x75, 0x96, 0xc8, 0x68, 0x63, 0xf2, 0x6b, 0xa0, 0xa4, 0xc9, 0x99, 0x16, 0x3c, 0x71, + 0x9e, 0x49, 0x50, 0x33, 0x1d, 0x2e, 0xc2, 0x78, 0x93, 0x10, 0x66, 0xa3, 0x69, 0xfe, 0x52, 0xd1, + 0xe1, 0x8e, 0xa5, 0x6c, 0x80, 0x4a, 0x73, 0x39, 0xe4, 0x38, 0xe4, 0x10, 0x5b, 0x46, 0x70, 0x88, + 0x9a, 0x86, 0x43, 0x82, 0x20, 0x91, 0xd2, 0xb1, 0xaa, 0x7e, 0x93, 0x13, 0xec, 0x1d, 0xa2, 0xe6, + 0x6d, 0x12, 0x04, 0x2c, 0x22, 0xdd, 0x87, 0x19, 0x9a, 0x75, 0xb2, 0x3d, 0x51, 0xbd, 0x32, 0x73, + 0xaa, 0x7a, 0x65, 0xda, 0xb5, 0x3d, 0xca, 0x79, 0x93, 0x97, 0x2d, 0x94, 0x2f, 0x6a, 0xa7, 0xf8, + 0x16, 0x4e, 0xc9, 0x17, 0xb5, 0x3b, 0x7c, 0x37, 0xbe, 0xfd, 0xc3, 0x2f, 0x3f, 0x59, 0xed, 0x5c, + 0xca, 0x9f, 0x7c, 0xf9, 0xc9, 0xea, 0xcb, 0x51, 0x13, 0xaa, 0xdd, 0x69, 0x43, 0x49, 0xae, 0x7d, + 0x94, 0x40, 0x66, 0xa7, 0x45, 0xb4, 0xf8, 0x4b, 0x8e, 0x45, 0x0b, 0xfe, 0x46, 0x9d, 0x41, 0xb4, + 0xb8, 0x02, 0x53, 0x49, 0xe7, 0x89, 0x83, 0x45, 0xc2, 0x67, 0x06, 0xb4, 0x2b, 0x8e, 0xaf, 0x6a, + 0x16, 0x73, 0xa4, 0x6a, 0x76, 0x5a, 0xa8, 0xfa, 0xb7, 0x61, 0xa6, 0x2a, 0x7f, 0x37, 0xfe, 0x1f, + 0x54, 0x4d, 0xba, 0xf6, 0xc8, 0x09, 0x5c, 0x7b, 0xf4, 0xa4, 0xae, 0x3d, 0xf6, 0x3f, 0x72, 0xed, + 0xf1, 0x17, 0xea, 0xda, 0xd9, 0x83, 0x8b, 0xce, 0x3b, 0x3b, 0x2d, 0xce, 0xfb, 0x9f, 0xe7, 0xd8, + 0x33, 0xb9, 0x87, 0xc3, 0x6d, 0xe2, 0xba, 0x2d, 0xcf, 0x0e, 0x9f, 0xdc, 0x23, 0xc4, 0xa1, 0xf9, + 0x7f, 0x88, 0x69, 0xce, 0x9c, 0x7a, 0x78, 0xfb, 0xe5, 0x73, 0xc7, 0x48, 0x0c, 0xee, 0xc2, 0xa4, + 0xcf, 0x18, 0x27, 0x5b, 0xa1, 0x95, 0x93, 0x15, 0x94, 0x3a, 0x70, 0x16, 0xec, 0x18, 0xdf, 0x87, + 0xf9, 0x64, 0xdd, 0x68, 0xc5, 0x36, 0x1f, 0x39, 0x95, 0xcd, 0x15, 0xa7, 0x53, 0x64, 0x5a, 0x91, + 0xe1, 0xdf, 0xa4, 0x86, 0x8f, 0x75, 0xa3, 0x66, 0xbf, 0x26, 0x35, 0xbb, 0xdc, 0x7e, 0x51, 0x0e, + 0x2e, 0x5f, 0x14, 0x47, 0xf0, 0xeb, 0x73, 0xac, 0x90, 0xd9, 0x27, 0xf5, 0xba, 0x83, 0xe3, 0x07, + 0x3b, 0xf4, 0x89, 0xe3, 0x60, 0xff, 0xac, 0x4f, 0x60, 0x0f, 0x66, 0x9b, 0xd8, 0x77, 0xed, 0x20, + 0x60, 0xed, 0x39, 0x56, 0x1c, 0xb0, 0x73, 0x38, 0xbf, 0xfe, 0x4a, 0x57, 0x8d, 0xb1, 0xd9, 0x0a, + 0x1b, 0x1f, 0xde, 0x13, 0xe4, 0xbc, 0x94, 0xd0, 0x0b, 0xcd, 0xcc, 0x0c, 0x4d, 0xcf, 0xe2, 0xca, + 0x2a, 0x6a, 0x98, 0x45, 0xc3, 0x8d, 0x37, 0xb2, 0xd6, 0x5b, 0x95, 0x5a, 0x4f, 0xaa, 0xba, 0xa6, + 0xb1, 0xa4, 0x59, 0xba, 0x16, 0xdb, 0x6e, 0xb5, 0x02, 0x0b, 0x52, 0x94, 0xca, 0x04, 0x8c, 0xbe, + 0xa5, 0x6f, 0xde, 0xd9, 0x2f, 0x0c, 0x29, 0x00, 0x63, 0xfa, 0xad, 0xfb, 0x77, 0xdf, 0xb9, 0x55, + 0xc8, 0xad, 0xff, 0x7e, 0x16, 0x86, 0x77, 0x83, 0xba, 0xf2, 0x00, 0x26, 0x93, 0x4d, 0xd6, 0x72, + 0x97, 0xee, 0xe9, 0x5e, 0xb0, 0xfa, 0xb5, 0x01, 0x04, 0xa2, 0x01, 0xfa, 0x3e, 0x9c, 0xcf, 0x34, + 0x70, 0x35, 0xe9, 0xd6, 0x14, 0x8d, 0xba, 0x3a, 0x98, 0x46, 0x48, 0x78, 0x00, 0x93, 0xc9, 0x2e, + 0xa3, 0x14, 0x7a, 0x82, 0x40, 0x0e, 0x5d, 0xd2, 0xfa, 0x53, 0x1e, 0x41, 0xa1, 0xab, 0xed, 0x77, + 0x55, 0xbe, 0x39, 0x4d, 0xa5, 0xbe, 0x7a, 0x1c, 0x2a, 0x21, 0xa7, 0x0d, 0x17, 0x7a, 0xb4, 0x62, + 0xa4, 0x66, 0x90, 0xd3, 0xaa, 0xeb, 0xc7, 0xa7, 0x15, 0x92, 0x09, 0xcc, 0xc9, 0xda, 0x29, 0x3d, + 0x2c, 0xd4, 0x45, 0xa8, 0x56, 0x8f, 0x49, 0x28, 0x04, 0xbe, 0x07, 0xd3, 0xe9, 0x36, 0xc9, 0x15, + 0x19, 0x87, 0x14, 0x89, 0xfa, 0xf5, 0x81, 0x24, 0x82, 0xfd, 0x21, 0x2c, 0x48, 0xeb, 0xfb, 0x1e, + 0x86, 0x94, 0xb6, 0x02, 0x7a, 0x18, 0xb2, 0x6f, 0xdb, 0x40, 0x31, 0x61, 0x26, 0xdb, 0x32, 0x58, + 0x96, 0xb1, 0xc9, 0x10, 0xa9, 0xd7, 0x8e, 0x41, 0x24, 0x84, 0xfc, 0x00, 0x8a, 0x3d, 0xcb, 0xfe, + 0x1e, 0x1e, 0x27, 0xa7, 0x56, 0x5f, 0x3b, 0x09, 0xb5, 0x90, 0xff, 0xb3, 0x1c, 0x5c, 0xee, 0x5f, + 0xb2, 0xaf, 0xc9, 0xf8, 0xf6, 0xdd, 0xa2, 0xbe, 0x7e, 0xe2, 0x2d, 0x49, 0xef, 0x95, 0x95, 0xe8, + 0x52, 0xef, 0x95, 0x10, 0xca, 0xbd, 0xb7, 0x4f, 0x2d, 0xae, 0x3c, 0x84, 0xa9, 0xd4, 0xaf, 0x32, + 0x4b, 0xf2, 0x2b, 0xd7, 0xa1, 0x50, 0x57, 0x06, 0x51, 0x08, 0xde, 0xbf, 0xca, 0x41, 0x79, 0xd0, + 0x8f, 0xaf, 0x37, 0x7a, 0xdb, 0xaa, 0xe7, 0x26, 0xf5, 0x8d, 0x53, 0x6c, 0x4a, 0x46, 0xef, 0x4c, + 0xeb, 0x41, 0xeb, 0xe1, 0x3a, 0x09, 0x1a, 0x79, 0xf4, 0x96, 0x37, 0x1e, 0x68, 0x90, 0xed, 0x6a, + 0x3a, 0x48, 0x83, 0x6c, 0x96, 0x4a, 0x1e, 0x64, 0x7b, 0x95, 0x2c, 0x54, 0x4e, 0x57, 0xb9, 0x72, + 0xb5, 0xf7, 0xed, 0x1b, 0x24, 0xa7, 0x57, 0xbd, 0x40, 0xe5, 0x74, 0xd5, 0x0a, 0x57, 0x7b, 0x1f, + 0xc1, 0x20, 0x39, 0xbd, 0xf2, 0x54, 0xfa, 0x68, 0xf4, 0xc8, 0x51, 0xa5, 0xd6, 0x97, 0xd3, 0xca, + 0x63, 0x5d, 0xff, 0xf4, 0x4c, 0x69, 0xc1, 0x82, 0x3c, 0x35, 0x93, 0x06, 0x6a, 0x29, 0xa9, 0xba, + 0x76, 0x6c, 0xd2, 0x58, 0xec, 0xd6, 0xed, 0xcf, 0x9e, 0x96, 0x72, 0x9f, 0x3f, 0x2d, 0xe5, 0xfe, + 0xfd, 0xb4, 0x94, 0xfb, 0xc5, 0xb3, 0xd2, 0xd0, 0xe7, 0xcf, 0x4a, 0x43, 0x7f, 0x7f, 0x56, 0x1a, + 0x7a, 0xb8, 0x9e, 0x48, 0x67, 0xf7, 0x18, 0xdb, 0xeb, 0xb7, 0x51, 0x2d, 0xa8, 0x46, 0xa9, 0xd5, + 0xc1, 0xda, 0xeb, 0xc9, 0xf4, 0x8a, 0xa5, 0xb7, 0xb5, 0x31, 0xf6, 0x5f, 0x0f, 0x37, 0xfe, 0x1b, + 0x00, 0x00, 0xff, 0xff, 0x77, 0xf5, 0x3e, 0xb4, 0xc0, 0x21, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2272,6 +2419,7 @@ type MsgClient interface { DeleteTradeRoute(ctx context.Context, in *MsgDeleteTradeRoute, opts ...grpc.CallOption) (*MsgDeleteTradeRouteResponse, error) UpdateTradeRoute(ctx context.Context, in *MsgUpdateTradeRoute, opts ...grpc.CallOption) (*MsgUpdateTradeRouteResponse, error) SetCommunityPoolRebate(ctx context.Context, in *MsgSetCommunityPoolRebate, opts ...grpc.CallOption) (*MsgSetCommunityPoolRebateResponse, error) + ToggleTradeController(ctx context.Context, in *MsgToggleTradeController, opts ...grpc.CallOption) (*MsgToggleTradeControllerResponse, error) } type msgClient struct { @@ -2453,6 +2601,15 @@ func (c *msgClient) SetCommunityPoolRebate(ctx context.Context, in *MsgSetCommun return out, nil } +func (c *msgClient) ToggleTradeController(ctx context.Context, in *MsgToggleTradeController, opts ...grpc.CallOption) (*MsgToggleTradeControllerResponse, error) { + out := new(MsgToggleTradeControllerResponse) + err := c.cc.Invoke(ctx, "/stride.stakeibc.Msg/ToggleTradeController", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { LiquidStake(context.Context, *MsgLiquidStake) (*MsgLiquidStakeResponse, error) @@ -2474,6 +2631,7 @@ type MsgServer interface { DeleteTradeRoute(context.Context, *MsgDeleteTradeRoute) (*MsgDeleteTradeRouteResponse, error) UpdateTradeRoute(context.Context, *MsgUpdateTradeRoute) (*MsgUpdateTradeRouteResponse, error) SetCommunityPoolRebate(context.Context, *MsgSetCommunityPoolRebate) (*MsgSetCommunityPoolRebateResponse, error) + ToggleTradeController(context.Context, *MsgToggleTradeController) (*MsgToggleTradeControllerResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -2537,6 +2695,9 @@ func (*UnimplementedMsgServer) UpdateTradeRoute(ctx context.Context, req *MsgUpd func (*UnimplementedMsgServer) SetCommunityPoolRebate(ctx context.Context, req *MsgSetCommunityPoolRebate) (*MsgSetCommunityPoolRebateResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method SetCommunityPoolRebate not implemented") } +func (*UnimplementedMsgServer) ToggleTradeController(ctx context.Context, req *MsgToggleTradeController) (*MsgToggleTradeControllerResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ToggleTradeController not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -2884,6 +3045,24 @@ func _Msg_SetCommunityPoolRebate_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _Msg_ToggleTradeController_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgToggleTradeController) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).ToggleTradeController(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/stride.stakeibc.Msg/ToggleTradeController", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ToggleTradeController(ctx, req.(*MsgToggleTradeController)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "stride.stakeibc.Msg", HandlerType: (*MsgServer)(nil), @@ -2964,6 +3143,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "SetCommunityPoolRebate", Handler: _Msg_SetCommunityPoolRebate_Handler, }, + { + MethodName: "ToggleTradeController", + Handler: _Msg_ToggleTradeController_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "stride/stakeibc/tx.proto", @@ -4551,6 +4734,78 @@ func (m *MsgSetCommunityPoolRebateResponse) MarshalToSizedBuffer(dAtA []byte) (i return len(dAtA) - i, nil } +func (m *MsgToggleTradeController) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgToggleTradeController) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgToggleTradeController) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintTx(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0x22 + } + if m.PermissionChange != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.PermissionChange)) + i-- + dAtA[i] = 0x18 + } + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintTx(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0x12 + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgToggleTradeControllerResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgToggleTradeControllerResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgToggleTradeControllerResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func encodeVarintTx(dAtA []byte, offset int, v uint64) int { offset -= sovTx(v) base := offset @@ -5239,6 +5494,39 @@ func (m *MsgSetCommunityPoolRebateResponse) Size() (n int) { return n } +func (m *MsgToggleTradeController) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.PermissionChange != 0 { + n += 1 + sovTx(uint64(m.PermissionChange)) + } + l = len(m.Address) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgToggleTradeControllerResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func sovTx(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -10006,6 +10294,221 @@ func (m *MsgSetCommunityPoolRebateResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgToggleTradeController) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgToggleTradeController: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgToggleTradeController: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChainId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PermissionChange", wireType) + } + m.PermissionChange = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PermissionChange |= AuthzPermissionChange(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgToggleTradeControllerResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgToggleTradeControllerResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgToggleTradeControllerResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 From 472402759362a63b885a97eba35539e3d495223c Mon Sep 17 00:00:00 2001 From: sampocs Date: Wed, 20 Mar 2024 13:50:01 -0500 Subject: [PATCH 08/13] rebate calculation and fund community pool ICA (#1136) Co-authored-by: riley-stride <104941670+riley-stride@users.noreply.github.com> --- app/apptesting/test_helpers.go | 15 + proto/stride/stakeibc/host_zone.proto | 53 +- proto/stride/stakeibc/tx.proto | 5 +- .../client/cli/tx_register_host_zone.go | 12 +- .../cli/tx_set_community_pool_rebate.go | 8 +- x/stakeibc/keeper/community_pool.go | 61 +- x/stakeibc/keeper/community_pool_test.go | 93 +++ ...icqcallbacks_community_pool_ica_balance.go | 2 +- .../keeper/icqcallbacks_withdrawal_balance.go | 27 +- .../icqcallbacks_withdrawal_balance_test.go | 15 + .../icqcallbacks_withdrawal_reward_balance.go | 29 +- ...allbacks_withdrawal_reward_balance_test.go | 50 +- x/stakeibc/keeper/keeper_test.go | 1 + x/stakeibc/keeper/msg_server.go | 31 +- x/stakeibc/keeper/msg_server_test.go | 60 +- x/stakeibc/keeper/reward_converter.go | 132 +++++ x/stakeibc/keeper/reward_converter_test.go | 544 ++++++++++++++++++ x/stakeibc/types/errors.go | 2 + x/stakeibc/types/host_zone.go | 2 +- x/stakeibc/types/host_zone.pb.go | 294 ++++++---- x/stakeibc/types/host_zone_test.go | 8 +- .../types/message_register_host_zone.go | 22 +- .../message_set_community_pool_rebate.go | 14 +- .../message_set_community_pool_rebate_test.go | 88 +-- x/stakeibc/types/tx.pb.go | 373 ++++++------ 25 files changed, 1547 insertions(+), 394 deletions(-) diff --git a/app/apptesting/test_helpers.go b/app/apptesting/test_helpers.go index 93ae00697d..4c7591e4ad 100644 --- a/app/apptesting/test_helpers.go +++ b/app/apptesting/test_helpers.go @@ -407,6 +407,21 @@ func (s *AppTestHelper) CheckICATxNotSubmitted(portId, channelId string, icaFunc s.Require().Equal(startSequence, endSequence, "sequence number should NOT have incremented from tested function") } +// Helper function to check if multiple ICA txs were submitted by seeing if the sequence number +// incremented by more than 1 +func (s *AppTestHelper) CheckMulitpleICATxSubmitted(portId, channelId string, icaFunction func() error) { + // Get the sequence before the tested funciton is run + startSequence := s.MustGetNextSequenceNumber(portId, channelId) + + // Run the test function and confirm there's no error + err := icaFunction() + s.Require().NoError(err, "no error expected executing tested function") + + // Check that the sequence number incremented + endSequence := s.MustGetNextSequenceNumber(portId, channelId) + s.Require().Greater(endSequence, startSequence+1, "sequence number should have incremented twice from tested function") +} + // Constructs an ICA Packet Acknowledgement compatible with ibc-go v5+ func ICAPacketAcknowledgement(t *testing.T, msgType string, msgResponses []proto.Message) channeltypes.Acknowledgement { txMsgData := &sdk.TxMsgData{ diff --git a/proto/stride/stakeibc/host_zone.proto b/proto/stride/stakeibc/host_zone.proto index e000707945..7adbd7c05d 100644 --- a/proto/stride/stakeibc/host_zone.proto +++ b/proto/stride/stakeibc/host_zone.proto @@ -8,83 +8,128 @@ import "cosmos_proto/cosmos.proto"; option go_package = "github.com/Stride-Labs/stride/v19/x/stakeibc/types"; // CommunityPoolRebate stores the size of the community pool liquid stake -// and the rebate percentage +// (denominated in stTokens) and the rebate rate as a decimal message CommunityPoolRebate { - string rebate_percentage = 1 [ + // Rebate percentage as a decimal (e.g. 0.2 for 20%) + string rebate_rate = 1 [ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false ]; - string liquid_stake_amount = 2 [ + // Number of stTokens received from the community pool liquid stake + string liquid_staked_st_token_amount = 2 [ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false ]; } +// Core data structure to track liquid staking zones message HostZone { + // Chain ID of the host zone string chain_id = 1; + // Bech32 prefix of host zone's address string bech32prefix = 17; + // ConnectionID from Stride to the host zone (ID is on the stride side) string connection_id = 2; + // Transfer Channel ID from Stride to the host zone (ID is on the stride side) string transfer_channel_id = 12; - // ibc denom on stride + // ibc denom of the host zone's native token on stride string ibc_denom = 8; // native denom on host zone string host_denom = 9; + // The unbonding period in days (e.g. 21) uint64 unbonding_period = 26; + // List of validators that are delegated to repeated Validator validators = 3; + // Address that custodies native tokens during a liquid stake string deposit_address = 18 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + // ICA Address on the host zone responsible for collecting rewards string withdrawal_ica_address = 22 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + // ICA Address on the host zone responsible for commission string fee_ica_address = 23 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + // ICA Address on the host zone responsible for staking and unstaking string delegation_ica_address = 24 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + // ICA Address that receives unstaked tokens after they've finished unbonding string redemption_ica_address = 25 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + // ICA Address that receives tokens from a community pool to liquid stake or + // redeem In the case of a liquid stake, the community pool deposits native + // tokens In the case of a redemption, the community pool deposits stTokens string community_pool_deposit_ica_address = 30 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + // ICA Address that distributes tokens back to the community pool during a + // community pool liquid stake or redeem In the case of a liquid stake, the + // return address sends back stTokens In the case of a redemption, the return + // address sends back native tokens string community_pool_return_ica_address = 31 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + // Module account on Stride that receives native tokens from the deposit ICA + // and liquid stakes them string community_pool_stake_holding_address = 32 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + // Module account on Stride that receives stTokens from the deposit ICA and + // redeems them string community_pool_redeem_holding_address = 33 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + // Optional community pool address to send tokens to after a community pool + // liquid stake or redemption If this address is empty, the tokens are sent to + // the main community pool + string community_pool_treasury_address = 35 + [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + // The total delegated balance on the host zone string total_delegations = 13 [ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false ]; + // The redemption rate from the previous epoch string last_redemption_rate = 10 [ (cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false ]; + // The current redemption rate string redemption_rate = 11 [ (cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false ]; + // The min outer redemption rate bound - controlled only be governance + // The min inner bound cannot exceed this bound string min_redemption_rate = 20 [ (cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false ]; + // The max outer redemption rate bound - controlled only be governance + // The max inner bound cannot exceed this bound string max_redemption_rate = 21 [ (cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false ]; + // The min minner redemption rate bound - controlled by the admin + // If the redemption rate exceeds this bound, the host zone is halted string min_inner_redemption_rate = 28 [ (cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false ]; + // The max minner redemption rate bound - controlled by the admin + // If the redemption rate exceeds this bound, the host zone is halted string max_inner_redemption_rate = 29 [ (cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false ]; + // An optional fee rebate + // If there is no rebate for the host zone, this will be nil CommunityPoolRebate community_pool_rebate = 34; + // A boolean indicating whether the chain has LSM enabled bool lsm_liquid_stake_enabled = 27; + // A boolean indicating whether the chain is currently halted bool halted = 19; reserved 4, 5, 6, 7, 14, 15, 16; } diff --git a/proto/stride/stakeibc/tx.proto b/proto/stride/stakeibc/tx.proto index 529172dd6d..6e43395d3b 100644 --- a/proto/stride/stakeibc/tx.proto +++ b/proto/stride/stakeibc/tx.proto @@ -136,6 +136,7 @@ message MsgRegisterHostZone { (gogoproto.nullable) = false ]; bool lsm_liquid_stake_enabled = 15; + string community_pool_treasury_address = 16; } message MsgRegisterHostZoneResponse {} @@ -335,8 +336,8 @@ message MsgSetCommunityPoolRebate { (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false ]; - // Number of native tokens staked by the community pool - string liquid_staked_amount = 4 [ + // Number of stTokens recieved by the community pool after liquid staking + string liquid_staked_st_token_amount = 4 [ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false ]; diff --git a/x/stakeibc/client/cli/tx_register_host_zone.go b/x/stakeibc/client/cli/tx_register_host_zone.go index 5de0670d51..4face5c64f 100644 --- a/x/stakeibc/client/cli/tx_register_host_zone.go +++ b/x/stakeibc/client/cli/tx_register_host_zone.go @@ -13,8 +13,9 @@ import ( ) const ( - FlagMinRedemptionRate = "min-redemption-rate" - FlagMaxRedemptionRate = "max-redemption-rate" + FlagMinRedemptionRate = "min-redemption-rate" + FlagMaxRedemptionRate = "max-redemption-rate" + FlagCommunityPoolTreasuryAddress = "community-pool-treasury-address" ) var _ = strconv.Itoa(0) @@ -68,6 +69,11 @@ func CmdRegisterHostZone() *cobra.Command { } } + communityPoolTreasuryAddress, err := cmd.Flags().GetString(FlagCommunityPoolTreasuryAddress) + if err != nil { + return err + } + msg := types.NewMsgRegisterHostZone( clientCtx.GetFromAddress().String(), connectionId, @@ -79,6 +85,7 @@ func CmdRegisterHostZone() *cobra.Command { minRedemptionRate, maxRedemptionRate, lsmEnabled, + communityPoolTreasuryAddress, ) if err := msg.ValidateBasic(); err != nil { @@ -92,6 +99,7 @@ func CmdRegisterHostZone() *cobra.Command { flags.AddTxFlagsToCmd(cmd) cmd.Flags().String(FlagMinRedemptionRate, "", "minimum redemption rate") cmd.Flags().String(FlagMaxRedemptionRate, "", "maximum redemption rate") + cmd.Flags().String(FlagCommunityPoolTreasuryAddress, "", "community pool treasury address") return cmd } diff --git a/x/stakeibc/client/cli/tx_set_community_pool_rebate.go b/x/stakeibc/client/cli/tx_set_community_pool_rebate.go index 6fe24f76d4..4c56b7bebb 100644 --- a/x/stakeibc/client/cli/tx_set_community_pool_rebate.go +++ b/x/stakeibc/client/cli/tx_set_community_pool_rebate.go @@ -17,10 +17,10 @@ import ( func CmdSetCommunityPoolRebate() *cobra.Command { cmd := &cobra.Command{ - Use: "set-rebate [chain-id] [rebate-rate] [liquid-staked-amount]", + Use: "set-rebate [chain-id] [rebate-rate] [liquid-staked-sttoken-amount]", Short: "Registers or updates a community pool rebate", Long: strings.TrimSpace(`Registers a community pool rebate by specifying the rebate percentage (as a decimal) -and the amount liquid staked. +and the amount liquid staked, denominated in the number of stTokens received. E.g. to specify a 20% rebate, the rebate rate should be 0.2 If a 0.0 rebate or 0 token liquid stake is specified, the rebate will be deleted. @@ -32,7 +32,7 @@ If a 0.0 rebate or 0 token liquid stake is specified, the rebate will be deleted if err != nil { return fmt.Errorf("unable to parse rebate percentage: %s", err.Error()) } - liquidStakeAmount, ok := sdkmath.NewIntFromString(args[2]) + liquidStakedStTokenAmount, ok := sdkmath.NewIntFromString(args[2]) if !ok { return errors.New("unable to parse liquid stake amount") } @@ -46,7 +46,7 @@ If a 0.0 rebate or 0 token liquid stake is specified, the rebate will be deleted clientCtx.GetFromAddress().String(), chainId, rebatePercentage, - liquidStakeAmount, + liquidStakedStTokenAmount, ) if err := msg.ValidateBasic(); err != nil { return err diff --git a/x/stakeibc/keeper/community_pool.go b/x/stakeibc/keeper/community_pool.go index 0ef14da646..9ff63cacd6 100644 --- a/x/stakeibc/keeper/community_pool.go +++ b/x/stakeibc/keeper/community_pool.go @@ -224,16 +224,57 @@ func (k Keeper) RedeemCommunityPoolTokens(ctx sdk.Context, hostZone types.HostZo return nil } +// Builds a msg to send funds to a community pool +// If the community pool treasury address is specified on the host zone, the tokens are bank sent there +// Otherwise, a MsgFundCommunityPool is used to send tokens to the default community pool address +func (k Keeper) BuildFundCommunityPoolMsg( + ctx sdk.Context, + hostZone types.HostZone, + tokens sdk.Coins, + senderAccountType types.ICAAccountType, +) (fundMsg []proto.Message, err error) { + // Get the sender ICA address based on the account type + var sender string + switch senderAccountType { + case types.ICAAccountType_COMMUNITY_POOL_RETURN: + sender = hostZone.CommunityPoolReturnIcaAddress + case types.ICAAccountType_WITHDRAWAL: + sender = hostZone.WithdrawalIcaAddress + default: + return nil, errorsmod.Wrapf(types.ErrICATxFailed, + "fund community pool ICA can only be initiated from either the community pool return or withdrawal ICA account") + } + + // If the community pool treasury address is specified, bank send there + if hostZone.CommunityPoolTreasuryAddress != "" { + fundMsg = []proto.Message{&banktypes.MsgSend{ + FromAddress: sender, + ToAddress: hostZone.CommunityPoolTreasuryAddress, + Amount: tokens, + }} + } else { + // Otherwise, call MsgFundCommunityPool + fundMsg = []proto.Message{&disttypes.MsgFundCommunityPool{ + Amount: tokens, + Depositor: sender, + }} + } + + return fundMsg, nil +} + // Using tokens in the CommunityPoolReturnIcaAddress, trigger ICA tx to fund community pool // Note: The denom of the passed in token has to be the denom which exists on the hostZone not Stride -func (k Keeper) FundCommunityPool(ctx sdk.Context, hostZone types.HostZone, token sdk.Coin) error { - fundCoins := sdk.NewCoins(token) - - var msgs []proto.Message - msgs = append(msgs, &disttypes.MsgFundCommunityPool{ - Amount: fundCoins, - Depositor: hostZone.CommunityPoolReturnIcaAddress, - }) +func (k Keeper) FundCommunityPool( + ctx sdk.Context, + hostZone types.HostZone, + token sdk.Coin, + senderAccountType types.ICAAccountType, +) error { + msgs, err := k.BuildFundCommunityPoolMsg(ctx, hostZone, sdk.NewCoins(token), senderAccountType) + if err != nil { + return err + } // Timeout the ICA at the end of the epoch strideEpochTracker, found := k.GetEpochTracker(ctx, epochstypes.STRIDE_EPOCH) @@ -247,10 +288,10 @@ func (k Keeper) FundCommunityPool(ctx sdk.Context, hostZone types.HostZone, toke var icaCallbackData []byte // Send the transaction through SubmitTx to kick off ICA command - _, err := k.SubmitTxs(ctx, + _, err = k.SubmitTxs(ctx, hostZone.ConnectionId, msgs, - types.ICAAccountType_COMMUNITY_POOL_RETURN, + senderAccountType, timeoutTimestamp, icaCallbackId, icaCallbackData) diff --git a/x/stakeibc/keeper/community_pool_test.go b/x/stakeibc/keeper/community_pool_test.go index 9872989fad..7e97f1d846 100644 --- a/x/stakeibc/keeper/community_pool_test.go +++ b/x/stakeibc/keeper/community_pool_test.go @@ -6,6 +6,7 @@ import ( sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types" "github.com/cosmos/gogoproto/proto" ibctesting "github.com/cosmos/ibc-go/v7/testing" @@ -438,3 +439,95 @@ func (s *KeeperTestSuite) TestRedeemCommunityPoolTokens_Failure_NotEnoughDelegat err := s.App.StakeibcKeeper.RedeemCommunityPoolTokens(s.Ctx, invalidHostZone) s.Require().ErrorContains(err, "invalid amount") } + +// ---------------------------------------------------------- +// BuildFundCommunityPoolMsg +// ---------------------------------------------------------- + +func (s *KeeperTestSuite) TestBuildFundCommunityPoolMsg() { + withdrawalICA := "withdrawal_ica" + communityPoolReturnICA := "community_pool_return_ica" + communityPoolTreasuryAddress := "community_pool_treasury" + + testCases := []struct { + name string + senderAccoutType types.ICAAccountType + sendToTreasury bool + expectedSender string + expectedReceiver string + expectedError string + }{ + { + name: "community pool return ICA to main community pool", + senderAccoutType: types.ICAAccountType_COMMUNITY_POOL_RETURN, + sendToTreasury: false, + expectedSender: communityPoolReturnICA, + }, + { + name: "community pool return ICA to treasury", + senderAccoutType: types.ICAAccountType_COMMUNITY_POOL_RETURN, + sendToTreasury: true, + expectedSender: communityPoolReturnICA, + expectedReceiver: communityPoolTreasuryAddress, + }, + { + name: "withdrawal ICA to main community pool", + senderAccoutType: types.ICAAccountType_WITHDRAWAL, + sendToTreasury: false, + expectedSender: withdrawalICA, + }, + { + name: "withdrawal ICA to treasury", + senderAccoutType: types.ICAAccountType_WITHDRAWAL, + sendToTreasury: true, + expectedSender: withdrawalICA, + expectedReceiver: communityPoolTreasuryAddress, + }, + { + name: "invalid sender", + senderAccoutType: types.ICAAccountType_DELEGATION, + expectedError: "fund community pool ICA can only be initiated from", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + // Define the sending tokens and input host zone struct + // If the test case sends to the treasury, we have to set the community pool treasury + // address to be non-empty + tokens := sdk.NewCoins(sdk.NewCoin(HostDenom, sdk.NewInt(1000))) + hostZone := types.HostZone{ + CommunityPoolReturnIcaAddress: communityPoolReturnICA, + WithdrawalIcaAddress: withdrawalICA, + } + if tc.sendToTreasury { + hostZone.CommunityPoolTreasuryAddress = communityPoolTreasuryAddress + } + + // Build the fund msg + actualMsg, actualErr := s.App.StakeibcKeeper.BuildFundCommunityPoolMsg(s.Ctx, hostZone, tokens, tc.senderAccoutType) + + // If there's not error expected, validate the underlying message + if tc.expectedError == "" { + s.Require().Len(actualMsg, 1, "there should be one message") + + // If the recipient was the treasury, confirm it was a valid bank send + if tc.sendToTreasury { + bankSendMsg, ok := actualMsg[0].(*banktypes.MsgSend) + s.Require().True(ok, "ICA message should have been a bank send") + s.Require().Equal(tokens, bankSendMsg.Amount, "bank send amount") + s.Require().Equal(tc.expectedSender, bankSendMsg.FromAddress, "bank send from address") + s.Require().Equal(tc.expectedReceiver, bankSendMsg.ToAddress, "bank send to address") + } else { + fundCommunityPoolMsg, ok := actualMsg[0].(*disttypes.MsgFundCommunityPool) + s.Require().True(ok, "ICA message should have been a fund community pool message") + s.Require().Equal(tokens, fundCommunityPoolMsg.Amount, "fund community pool amount") + s.Require().Equal(tc.expectedSender, fundCommunityPoolMsg.Depositor, "bank send from address") + } + } else { + // If there was an expected error, confirm the error message + s.Require().ErrorContains(actualErr, tc.expectedError) + } + }) + } +} diff --git a/x/stakeibc/keeper/icqcallbacks_community_pool_ica_balance.go b/x/stakeibc/keeper/icqcallbacks_community_pool_ica_balance.go index 66350db561..87767e82c9 100644 --- a/x/stakeibc/keeper/icqcallbacks_community_pool_ica_balance.go +++ b/x/stakeibc/keeper/icqcallbacks_community_pool_ica_balance.go @@ -75,7 +75,7 @@ func CommunityPoolIcaBalanceCallback(k Keeper, ctx sdk.Context, args []byte, que } else if icaType == types.ICAAccountType_COMMUNITY_POOL_RETURN { // Send ICA msg to FundCommunityPool with token found in return ICA err := utils.ApplyFuncIfNoError(ctx, func(c sdk.Context) error { - return k.FundCommunityPool(ctx, hostZone, token) + return k.FundCommunityPool(ctx, hostZone, token, icaType) }) if err != nil { k.Logger(ctx).Error(utils.LogICQCallbackWithHostZone(chainId, ICQCallbackID_CommunityPoolIcaBalance, diff --git a/x/stakeibc/keeper/icqcallbacks_withdrawal_balance.go b/x/stakeibc/keeper/icqcallbacks_withdrawal_balance.go index 3eda1f59cb..49aefa89f0 100644 --- a/x/stakeibc/keeper/icqcallbacks_withdrawal_balance.go +++ b/x/stakeibc/keeper/icqcallbacks_withdrawal_balance.go @@ -1,16 +1,12 @@ package keeper import ( - "fmt" - sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" errorsmod "cosmossdk.io/errors" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/gogoproto/proto" - "github.com/spf13/cast" icqkeeper "github.com/Stride-Labs/stride/v19/x/interchainquery/keeper" @@ -62,27 +58,10 @@ func WithdrawalBalanceCallback(k Keeper, ctx sdk.Context, args []byte, query icq return errorsmod.Wrapf(types.ErrICAAccountNotFound, "no fee account found for %s", chainId) } - // Determine the stride commission rate to the relevant portion can be sent to the fee account - params := k.GetParams(ctx) - strideCommissionInt, err := cast.ToInt64E(params.StrideCommission) + // Split the withdrawal amount into the stride fee and reinvest portion + feeAmount, reinvestAmount, err := k.CalculateRewardsSplitAfterRebate(ctx, hostZone, withdrawalBalanceAmount) if err != nil { - return err - } - - // check that stride commission is between 0 and 1 - strideCommission := sdk.NewDec(strideCommissionInt).Quo(sdk.NewDec(100)) - if strideCommission.LT(sdk.ZeroDec()) || strideCommission.GT(sdk.OneDec()) { - return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Aborting withdrawal balance callback -- Stride commission must be between 0 and 1!") - } - - // Split out the reinvestment amount from the fee amount - feeAmount := strideCommission.Mul(sdk.NewDecFromInt(withdrawalBalanceAmount)).TruncateInt() - reinvestAmount := withdrawalBalanceAmount.Sub(feeAmount) - - // Safety check, balances should add to original amount - if !feeAmount.Add(reinvestAmount).Equal(withdrawalBalanceAmount) { - k.Logger(ctx).Error(fmt.Sprintf("Error with withdraw logic: %v, Fee Portion: %v, Reinvest Portion %v", withdrawalBalanceAmount, feeAmount, reinvestAmount)) - return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Failed to subdivide rewards to commission and delegationAccount") + return errorsmod.Wrapf(err, "unable to split reward amount into fee and reinvest amounts") } // Prepare MsgSends from the withdrawal account diff --git a/x/stakeibc/keeper/icqcallbacks_withdrawal_balance_test.go b/x/stakeibc/keeper/icqcallbacks_withdrawal_balance_test.go index acabf7a66d..f920b54bde 100644 --- a/x/stakeibc/keeper/icqcallbacks_withdrawal_balance_test.go +++ b/x/stakeibc/keeper/icqcallbacks_withdrawal_balance_test.go @@ -228,6 +228,21 @@ func (s *KeeperTestSuite) TestWithdrawalBalanceCallback_NoFeeAccount() { s.Require().EqualError(err, "no fee account found for GAIA: ICA acccount not found on host zone") } +func (s *KeeperTestSuite) TestWithdrawalBalanceCallback_FailedToCheckForRebate() { + tc := s.SetupWithdrawalBalanceCallbackTest() + + // Add a rebate to the host zone - since there are no stTokens in supply, the test will fail + hostZone := s.MustGetHostZone(HostChainId) + hostZone.CommunityPoolRebate = &types.CommunityPoolRebate{ + RebateRate: sdk.MustNewDecFromStr("0.5"), + LiquidStakedStTokenAmount: sdkmath.NewInt(1), + } + s.App.StakeibcKeeper.SetHostZone(s.Ctx, hostZone) + + err := keeper.WithdrawalBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.validArgs.callbackArgs, tc.validArgs.query) + s.Require().ErrorContains(err, "unable to split reward amount into fee and reinvest amounts") +} + func (s *KeeperTestSuite) TestWithdrawalBalanceCallback_FailedSubmitTx() { tc := s.SetupWithdrawalBalanceCallbackTest() diff --git a/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance.go b/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance.go index d83d66b4b9..8ce18ad977 100644 --- a/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance.go +++ b/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance.go @@ -24,6 +24,10 @@ func WithdrawalRewardBalanceCallback(k Keeper, ctx sdk.Context, args []byte, que "Starting withdrawal reward balance callback, QueryId: %vs, QueryType: %s, Connection: %s", query.Id, query.QueryType, query.ConnectionId)) chainId := query.ChainId + hostZone, err := k.GetActiveHostZone(ctx, chainId) + if err != nil { + return err + } // Unmarshal the query response args to determine the balance withdrawalRewardBalanceAmount, err := icqkeeper.UnmarshalAmountFromBalanceQuery(k.cdc, args) @@ -54,14 +58,33 @@ func WithdrawalRewardBalanceCallback(k Keeper, ctx sdk.Context, args []byte, que k.Logger(ctx).Info(utils.LogICQCallbackWithHostZone(chainId, ICQCallbackID_WithdrawalRewardBalance, "Query response - Withdrawal Reward Balance: %v %s", withdrawalRewardBalanceAmount, tradeRoute.RewardDenomOnHostZone)) - // Using ICA commands on the withdrawal address, transfer the found reward tokens from the host zone to the trade zone - if err := k.TransferRewardTokensHostToTrade(ctx, withdrawalRewardBalanceAmount, tradeRoute); err != nil { + // Split the withdrawal amount into a rebate, stride fee, and reinvest portion + rebateAmount, tradeAmount, err := k.CalculateRewardsSplitBeforeRebate(ctx, hostZone, withdrawalRewardBalanceAmount) + if err != nil { + return errorsmod.Wrapf(err, "unable to check for rebate amount") + } + + // If there's a rebate portion, fund the community pool with that amount + if rebateAmount.GT(sdkmath.ZeroInt()) { + rebateToken := sdk.NewCoin(tradeRouteCallback.RewardDenom, rebateAmount) + if err := k.FundCommunityPool(ctx, hostZone, rebateToken, types.ICAAccountType_WITHDRAWAL); err != nil { + return errorsmod.Wrapf(err, "unable to submit fund community pool ICA") + } + + k.Logger(ctx).Info(utils.LogICQCallbackWithHostZone(chainId, ICQCallbackID_WithdrawalRewardBalance, + "Sending rebate tokens %v %s to community pool", + rebateAmount, tradeRoute.RewardDenomOnRewardZone)) + } + + // Transfer the amount leftover after to the rebate to the trade zone so it can be swapped for the native token + // We transfer both the amount to be reinvested, and the amount for the stride fee + if err := k.TransferRewardTokensHostToTrade(ctx, tradeAmount, tradeRoute); err != nil { return errorsmod.Wrapf(err, "initiating transfer of reward tokens to trade ICA failed") } k.Logger(ctx).Info(utils.LogICQCallbackWithHostZone(chainId, ICQCallbackID_WithdrawalRewardBalance, "Sending discovered reward tokens %v %s from hostZone to tradeZone", - withdrawalRewardBalanceAmount, tradeRoute.RewardDenomOnHostZone)) + tradeAmount, tradeRoute.RewardDenomOnRewardZone)) return nil } diff --git a/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance_test.go b/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance_test.go index 1299d87614..d9d1d2ad40 100644 --- a/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance_test.go +++ b/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance_test.go @@ -21,6 +21,12 @@ func (s *KeeperTestSuite) SetupWithdrawalRewardBalanceCallbackTestCase() Balance withdrawalAccountOwner := types.FormatHostZoneICAOwner(HostChainId, types.ICAAccountType_WITHDRAWAL) withdrawalChannelId, withdrawalPortId := s.CreateICAChannel(withdrawalAccountOwner) + s.App.StakeibcKeeper.SetHostZone(s.Ctx, types.HostZone{ + ChainId: HostChainId, + HostDenom: HostDenom, + ConnectionId: ibctesting.FirstConnectionID, + }) + route := types.TradeRoute{ RewardDenomOnRewardZone: RewardDenom, HostDenomOnHostZone: HostDenom, @@ -59,7 +65,10 @@ func (s *KeeperTestSuite) SetupWithdrawalRewardBalanceCallbackTestCase() Balance RewardDenom: RewardDenom, HostDenom: HostDenom, }) - query := icqtypes.Query{CallbackData: callbackDataBz} + query := icqtypes.Query{ + ChainId: HostChainId, + CallbackData: callbackDataBz, + } queryResponse := s.CreateBalanceQueryResponse(balance.Int64(), route.RewardDenomOnHostZone) return BalanceQueryCallbackTestCase{ @@ -102,6 +111,29 @@ func (s *KeeperTestSuite) TestWithdrawalRewardBalanceCallback_SuccessfulNoTransf }) } +// Verify that if the amount returned by the ICQ response is less than the min_swap_amount, no transfer happens +func (s *KeeperTestSuite) TestWithdrawalRewardBalanceCallback_SuccessfulWithRebate() { + tc := s.SetupWithdrawalRewardBalanceCallbackTestCase() + + // Update the host zone to have a rebate + stTokenSupply := sdkmath.NewInt(1_000_000) + hostZone := s.MustGetHostZone(HostChainId) + hostZone.TotalDelegations = sdkmath.NewInt(10_000_000) + hostZone.CommunityPoolRebate = &types.CommunityPoolRebate{ + RebateRate: sdk.MustNewDecFromStr("0.5"), + LiquidStakedStTokenAmount: stTokenSupply, + } + s.App.StakeibcKeeper.SetHostZone(s.Ctx, hostZone) + + // Mint stTokens so that the supply matches the liquid staked amount + s.FundAccount(s.TestAccs[0], sdk.NewCoin(types.StAssetDenomFromHostZoneDenom(hostZone.HostDenom), stTokenSupply)) + + // ICA inside of TransferRewardTokensHostToTrade should not actually execute because of min_swap_amount + s.CheckMulitpleICATxSubmitted(tc.PortID, tc.ChannelID, func() error { + return keeper.WithdrawalRewardBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.Response.CallbackArgs, tc.Response.Query) + }) +} + func (s *KeeperTestSuite) TestWithdrawalRewardBalanceCallback_ZeroBalance() { tc := s.SetupWithdrawalRewardBalanceCallbackTestCase() @@ -150,6 +182,22 @@ func (s *KeeperTestSuite) TestWithdrawalRewardBalanceCallback_TradeRouteNotFound s.Require().ErrorContains(err, "trade route not found") } +func (s *KeeperTestSuite) TestWithdrawalRewardBalanceCallback_FailedToCheckForRebate() { + tc := s.SetupWithdrawalRewardBalanceCallbackTestCase() + + // Add a rebate to the host zone and set the total delegations to 0 so the check fails + hostZone := s.MustGetHostZone(HostChainId) + hostZone.CommunityPoolRebate = &types.CommunityPoolRebate{ + RebateRate: sdk.MustNewDecFromStr("0.5"), + LiquidStakedStTokenAmount: sdkmath.NewInt(1), + } + hostZone.TotalDelegations = sdkmath.ZeroInt() + s.App.StakeibcKeeper.SetHostZone(s.Ctx, hostZone) + + err := keeper.WithdrawalRewardBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.Response.CallbackArgs, tc.Response.Query) + s.Require().ErrorContains(err, "unable to check for rebate amount") +} + func (s *KeeperTestSuite) TestWithdrawalRewardBalanceCallback_FailedSubmitTx() { tc := s.SetupWithdrawalRewardBalanceCallbackTestCase() diff --git a/x/stakeibc/keeper/keeper_test.go b/x/stakeibc/keeper/keeper_test.go index 4e39d6b18f..873baa9c74 100644 --- a/x/stakeibc/keeper/keeper_test.go +++ b/x/stakeibc/keeper/keeper_test.go @@ -33,6 +33,7 @@ var ( HostDenom = "udenom" RewardDenom = "ureward" + ValidHostAddress = "cosmos1uk4ze0x4nvh4fk0xm4jdud58eqn4yxhrgl2scj" ValAddress = "cosmosvaloper1uk4ze0x4nvh4fk0xm4jdud58eqn4yxhrdt795p" StrideICAAddress = "stride1gcx4yeplccq9nk6awzmm0gq8jf7yet80qj70tkwy0mz7pg87nepsen0l38" HostICAAddress = "cosmos1gcx4yeplccq9nk6awzmm0gq8jf7yet80qj70tkwy0mz7pg87nepswn2dj8" diff --git a/x/stakeibc/keeper/msg_server.go b/x/stakeibc/keeper/msg_server.go index 987b21ceb4..799917b498 100644 --- a/x/stakeibc/keeper/msg_server.go +++ b/x/stakeibc/keeper/msg_server.go @@ -112,6 +112,14 @@ func (k msgServer) RegisterHostZone(goCtx context.Context, msg *types.MsgRegiste return nil, errorsmod.Wrapf(err, "unable to create community pool redeem account for host zone %s", chainId) } + // Validate the community pool treasury address if it's non-empty + if msg.CommunityPoolTreasuryAddress != "" { + _, err := utils.AccAddressFromBech32(msg.CommunityPoolTreasuryAddress, msg.Bech32Prefix) + if err != nil { + return nil, errorsmod.Wrapf(err, "invalid community pool treasury address (%s)", msg.CommunityPoolTreasuryAddress) + } + } + params := k.GetParams(ctx) if msg.MinRedemptionRate.IsNil() || msg.MinRedemptionRate.IsZero() { msg.MinRedemptionRate = sdk.NewDecWithPrec(int64(params.DefaultMinRedemptionRateThreshold), 2) @@ -138,9 +146,10 @@ func (k msgServer) RegisterHostZone(goCtx context.Context, msg *types.MsgRegiste MinRedemptionRate: msg.MinRedemptionRate, MaxRedemptionRate: msg.MaxRedemptionRate, // Default the inner bounds to the outer bounds - MinInnerRedemptionRate: msg.MinRedemptionRate, - MaxInnerRedemptionRate: msg.MaxRedemptionRate, - LsmLiquidStakeEnabled: msg.LsmLiquidStakeEnabled, + MinInnerRedemptionRate: msg.MinRedemptionRate, + MaxInnerRedemptionRate: msg.MaxRedemptionRate, + LsmLiquidStakeEnabled: msg.LsmLiquidStakeEnabled, + CommunityPoolTreasuryAddress: msg.CommunityPoolTreasuryAddress, } // write the zone back to the store k.SetHostZone(ctx, zone) @@ -1117,14 +1126,22 @@ func (k msgServer) SetCommunityPoolRebate( return nil, types.ErrHostZoneNotFound.Wrapf("host zone %s not found", msg.ChainId) } - // If a zero rebate is specified, set the rebate to nil + // Get the current stToken supply and confirm it's greater than or equal to the liquid staked amount + stDenom := utils.StAssetDenomFromHostZoneDenom(hostZone.HostDenom) + stTokenSupply := k.bankKeeper.GetSupply(ctx, stDenom).Amount + if msg.LiquidStakedStTokenAmount.GT(stTokenSupply) { + return nil, types.ErrFailedToRegisterRebate.Wrapf("liquid staked stToken amount (%v) is greater than current supply (%v)", + msg.LiquidStakedStTokenAmount, stTokenSupply) + } + + // If a zero rebate rate or zero LiquidStakedStTokenAmount is specified, set the rebate to nil // Otherwise, update the struct - if msg.LiquidStakedAmount.IsZero() || msg.RebateRate.IsZero() { + if msg.LiquidStakedStTokenAmount.IsZero() || msg.RebateRate.IsZero() { hostZone.CommunityPoolRebate = nil } else { hostZone.CommunityPoolRebate = &types.CommunityPoolRebate{ - LiquidStakeAmount: msg.LiquidStakedAmount, - RebatePercentage: msg.RebateRate, + LiquidStakedStTokenAmount: msg.LiquidStakedStTokenAmount, + RebateRate: msg.RebateRate, } } diff --git a/x/stakeibc/keeper/msg_server_test.go b/x/stakeibc/keeper/msg_server_test.go index 660a108d6c..028cc24b06 100644 --- a/x/stakeibc/keeper/msg_server_test.go +++ b/x/stakeibc/keeper/msg_server_test.go @@ -13,6 +13,7 @@ import ( channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ibctesting "github.com/cosmos/ibc-go/v7/testing" + "github.com/Stride-Labs/stride/v19/utils" epochtypes "github.com/Stride-Labs/stride/v19/x/epochs/types" icqtypes "github.com/Stride-Labs/stride/v19/x/interchainquery/types" recordstypes "github.com/Stride-Labs/stride/v19/x/records/types" @@ -169,6 +170,21 @@ func (s *KeeperTestSuite) TestRegisterHostZone_Success() { s.Require().Equal(expectedDepositRecord, depositRecords[0], "deposit record") } +func (s *KeeperTestSuite) TestRegisterHostZone_Success_SetCommunityPoolTreasuryAddress() { + tc := s.SetupRegisterHostZone() + + // Sets the community pool treasury address to a valid address + msg := tc.validMsg + msg.CommunityPoolTreasuryAddress = ValidHostAddress + + _, err := s.GetMsgServer().RegisterHostZone(sdk.WrapSDKContext(s.Ctx), &msg) + s.Require().NoError(err, "no error expected when registering host with valid treasury address") + + // Confirm treasury address was set + hostZone := s.MustGetHostZone(HostChainId) + s.Require().Equal(ValidHostAddress, hostZone.CommunityPoolTreasuryAddress, "treasury address") +} + func (s *KeeperTestSuite) TestRegisterHostZone_InvalidConnectionId() { tc := s.SetupRegisterHostZone() msg := tc.validMsg @@ -383,6 +399,17 @@ func (s *KeeperTestSuite) TestRegisterHostZone_CannotRegisterRedemptionAccount() s.Require().EqualError(err, expectedErrMsg, "can't register redemption account") } +func (s *KeeperTestSuite) TestRegisterHostZone_InvalidCommunityPoolTreasuryAddress() { + // tests for a failure if the community pool treasury address is invalid + tc := s.SetupRegisterHostZone() + + invalidMsg := tc.validMsg + invalidMsg.CommunityPoolTreasuryAddress = "invalid_address" + + _, err := s.GetMsgServer().RegisterHostZone(sdk.WrapSDKContext(s.Ctx), &invalidMsg) + s.Require().ErrorContains(err, "invalid community pool treasury address") +} + // ---------------------------------------------------- // AddValidator // ---------------------------------------------------- @@ -2581,34 +2608,47 @@ func (s *KeeperTestSuite) TestResumeHostZone_UnhaltedZones() { // ---------------------------------------------------- func (s *KeeperTestSuite) TestSetCommunityPoolRebate() { + stTokenSupply := sdk.NewInt(2000) rebateInfo := types.CommunityPoolRebate{ - LiquidStakeAmount: sdk.NewInt(1000), - RebatePercentage: sdk.MustNewDecFromStr("0.5"), + RebateRate: sdk.MustNewDecFromStr("0.5"), + LiquidStakedStTokenAmount: sdk.NewInt(1000), } + // Mint stTokens so the supply is populated + s.FundAccount(s.TestAccs[0], sdk.NewCoin(utils.StAssetDenomFromHostZoneDenom(HostDenom), stTokenSupply)) + // Set host zone with no rebate hostZone := types.HostZone{ - ChainId: HostChainId, + ChainId: HostChainId, + HostDenom: HostDenom, } s.App.StakeibcKeeper.SetHostZone(s.Ctx, hostZone) // Submit a message to create the rebate - msg := types.MsgSetCommunityPoolRebate{ - ChainId: HostChainId, - RebateRate: rebateInfo.RebatePercentage, - LiquidStakedAmount: rebateInfo.LiquidStakeAmount, + registerMsg := types.MsgSetCommunityPoolRebate{ + ChainId: HostChainId, + RebateRate: rebateInfo.RebateRate, + LiquidStakedStTokenAmount: rebateInfo.LiquidStakedStTokenAmount, } - _, err := s.GetMsgServer().SetCommunityPoolRebate(s.Ctx, &msg) + _, err := s.GetMsgServer().SetCommunityPoolRebate(s.Ctx, ®isterMsg) s.Require().NoError(err, "no error expected when registering rebate") // Confirm the rebate was updated actualHostZone := s.MustGetHostZone(HostChainId) s.Require().Equal(rebateInfo, *actualHostZone.CommunityPoolRebate, "rebate was updated on host zone") + // Attempt to update the rebate with a large liquid stake amount, it should fail + invalidMsg := types.MsgSetCommunityPoolRebate{ + ChainId: HostChainId, + LiquidStakedStTokenAmount: sdk.NewInt(1_000_000), + } + _, err = s.GetMsgServer().SetCommunityPoolRebate(s.Ctx, &invalidMsg) + s.Require().ErrorContains(err, "liquid staked stToken amount (1000000) is greater than current supply (2000)") + // Submit a 0 LS amount which should delete the rebate removeMsg := types.MsgSetCommunityPoolRebate{ - ChainId: HostChainId, - LiquidStakedAmount: sdk.ZeroInt(), + ChainId: HostChainId, + LiquidStakedStTokenAmount: sdk.ZeroInt(), } _, err = s.GetMsgServer().SetCommunityPoolRebate(s.Ctx, &removeMsg) s.Require().NoError(err, "no error expected when registering 0 rebate") diff --git a/x/stakeibc/keeper/reward_converter.go b/x/stakeibc/keeper/reward_converter.go index 35d16050bd..78b1a8418a 100644 --- a/x/stakeibc/keeper/reward_converter.go +++ b/x/stakeibc/keeper/reward_converter.go @@ -34,6 +34,12 @@ type ForwardMetadata struct { Retries int64 `json:"retries"` } +type FeeInfo struct { + RebateAmount sdkmath.Int + StrideFeeAmount sdkmath.Int + ReinvestAmount sdkmath.Int +} + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // The goal of this code is to allow certain reward token types to be automatically traded into other types // This happens before the rest of the staking, allocation, distribution etc. would continue as normal @@ -53,6 +59,132 @@ type ForwardMetadata struct { // and the normal staking and distribution flow will continue from there. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Breaks down the split of non-native-denom rewards into the portions intended for a rebate vs the remainder +// that's used for fees and reinvestment +// For instance, in the case of dYdX, this is used on the USDC that has not been pushed through the trade route +// yet, and has not yet been converted to DYDX +// +// The rebate percentage is determined by: (% of total TVL contributed by commuity pool) * (rebate percentage) +// +// E.g. Community pool liquid staked 1M, TVL is 10M, rebate is 20% +// Total rewards this epoch are 1000, and the stride fee is 10% +// => Then the rebate is 1000 rewards * 10% stride fee * (1M / 10M) * 20% rebate = 2 +func (k Keeper) CalculateRewardsSplitBeforeRebate( + ctx sdk.Context, + hostZone types.HostZone, + rewardAmount sdkmath.Int, +) (rebateAmount sdkmath.Int, remainingAmount sdkmath.Int, err error) { + // Get the rebate info from the host zone if applicable + // If there's no rebate, return 0 rebate and the full reward as the remainder + rebateInfo, chainHasRebate := hostZone.SafelyGetCommunityPoolRebate() + if !chainHasRebate { + return sdkmath.ZeroInt(), rewardAmount, nil + } + + // Get the fee rate from params (e.g. 0.1 for a 10% fee) + strideFee := sdk.NewIntFromUint64(k.GetParams(ctx).StrideCommission) + strideFeeRate := sdk.NewDecFromInt(strideFee).Quo(sdk.NewDec(100)) + + // Get supply of stTokens to determine the portion of TVL that the community pool liquid stake makes up + stDenom := utils.StAssetDenomFromHostZoneDenom(hostZone.HostDenom) + stTokenSupply := k.bankKeeper.GetSupply(ctx, stDenom).Amount + + // It shouldn't be possible to have 0 token supply (since there are rewards and there was a community pool stake) + // This will also prevent a division by 0 error + if stTokenSupply.IsZero() { + return sdkmath.ZeroInt(), sdkmath.ZeroInt(), errorsmod.Wrapf(types.ErrDivisionByZero, + "unable to calculate rebate amount for %s since total delegations are 0", hostZone.ChainId) + } + + // It also shouldn't be possible for the liquid stake amount to be greater than the full TVL + if rebateInfo.LiquidStakedStTokenAmount.GT(stTokenSupply) { + return sdkmath.ZeroInt(), sdkmath.ZeroInt(), errorsmod.Wrapf(types.ErrFeeSplitInvariantFailed, + "community pool liquid staked amount greater than total delegations") + } + + // The rebate amount is determined by the contribution of the community pool stake towards the total TVL, + // multiplied by the rebate fee percentage + contributionRate := sdk.NewDecFromInt(rebateInfo.LiquidStakedStTokenAmount).Quo(sdk.NewDecFromInt(stTokenSupply)) + totalFeesAmount := sdk.NewDecFromInt(rewardAmount).Mul(strideFeeRate).TruncateInt() + rebateAmount = sdk.NewDecFromInt(totalFeesAmount).Mul(contributionRate).Mul(rebateInfo.RebateRate).TruncateInt() + remainingAmount = rewardAmount.Sub(rebateAmount) + + return rebateAmount, remainingAmount, nil +} + +// Given the native-denom reward balance from an ICQ, calculates the relevant portions earmarked as a +// stride fee vs for reinvestment +// This is called *after* a rebate has been issued (if there is one to begin with) +// The reward amount is denominated in the host zone's native denom - this is either directly from +// staking rewards, or, in the case of a host zone with a trade route, this is called with the converted tokens +// For instance, with dYdX, this is applied to the DYDX tokens that were converted from USDC +// +// If the chain doesn't have a rebate in place, the split is decided entirely from the stride commission percent +// However, if the chain does have a rebate, we need to factor that into the calculation, by scaling +// up the rewards to find the amount before the rebate +// +// For instance, if 1000 rewards were collected and 2 were sent as a rebate, then the stride fee should be based +// on the original 1000 rewards instead of the remaining 998 in the query response: +// +// Community pool liquid staked 1M, TVL is 10M, rebate is 20%, stride fee is 10% +// If 998 native tokens were queried, we have to scale that up to 1000 original reward tokens +// +// Effective Rebate Pct = 10% fees * (1M LS / 10M TVL) * 20% rebate = 0.20% (aka 0.002) +// Effective Stride Fee Pct = 10% fees - 0.20% effective rebate = 9.8% +// Original Reward Amount = 998 Queried Rewards / (1 - 0.002 effective rebate rate) = 1000 original rewards +// Then stride fees are 9.8% of that 1000 original rewards = 98 +func (k Keeper) CalculateRewardsSplitAfterRebate( + ctx sdk.Context, + hostZone types.HostZone, + rewardsAmount sdkmath.Int, +) (strideFeeAmount sdkmath.Int, reinvestAmount sdkmath.Int, err error) { + // Get the fee rate and total fees from params (e.g. 0.1 for 10% fee) + strideFee := sdk.NewIntFromUint64(k.GetParams(ctx).StrideCommission) + totalFeeRate := sdk.NewDecFromInt(strideFee).Quo(sdk.NewDec(100)) + + // Check if the chain has a rebate + rebateInfo, chainHasRebate := hostZone.SafelyGetCommunityPoolRebate() + + // If there's no rebate, the fee split just uses the commission + if !chainHasRebate { + strideFeeAmount = sdk.NewDecFromInt(rewardsAmount).Mul(totalFeeRate).TruncateInt() + } else { + // Get supply of stTokens to determine the portion of TVL that the community pool liquid stake makes up + stDenom := utils.StAssetDenomFromHostZoneDenom(hostZone.HostDenom) + stTokenSupply := k.bankKeeper.GetSupply(ctx, stDenom).Amount + + // It shouldn't be possible to have 0 token supply (since there are rewards and there was a community pool stake) + // This will also prevent a division by 0 error + if stTokenSupply.IsZero() { + return sdkmath.ZeroInt(), sdkmath.ZeroInt(), errorsmod.Wrapf(types.ErrDivisionByZero, + "unable to calculate rebate amount for %s since total delegations are 0", hostZone.ChainId) + } + + // It also shouldn't be possible for the liquid stake amount to be greater than the full TVL + if rebateInfo.LiquidStakedStTokenAmount.GT(stTokenSupply) { + return sdkmath.ZeroInt(), sdkmath.ZeroInt(), errorsmod.Wrapf(types.ErrFeeSplitInvariantFailed, + "community pool liquid staked amount greater than total delegations") + } + + // Otherwise, the rebate must be considered in the fee split + // The rebate portion is the portion of TVL contributed to by the liquid stake * the rebate percentage + // The stride fee poriton is the remaining percentage + contributionRate := sdk.NewDecFromInt(rebateInfo.LiquidStakedStTokenAmount).Quo(sdk.NewDecFromInt(stTokenSupply)) + effectiveRebateRate := totalFeeRate.Mul(contributionRate).Mul(rebateInfo.RebateRate) + effectiveStrideFeeRate := totalFeeRate.Sub(effectiveRebateRate) + + // Before calculating the fee, we have to scale up the rewards amount to the amount before the rebate + originalRewardScalingFactor := sdk.OneDec().Sub(effectiveRebateRate) + originalRewardsAmount := sdk.NewDecFromInt(rewardsAmount).Quo(originalRewardScalingFactor).TruncateDec() + strideFeeAmount = originalRewardsAmount.Mul(effectiveStrideFeeRate).Ceil().TruncateInt() // ceiling since rebate was truncated + } + + // Using the strideFeeAmount, back into the reinvest amount + reinvestAmount = rewardsAmount.Sub(strideFeeAmount) + + return strideFeeAmount, reinvestAmount, nil +} + // Builds an authz MsgGrant or MsgRevoke to grant an account trade capabilties on behalf of the trade ICA func (k Keeper) BuildTradeAuthzMsg( ctx sdk.Context, diff --git a/x/stakeibc/keeper/reward_converter_test.go b/x/stakeibc/keeper/reward_converter_test.go index e788c08b66..5b5e066760 100644 --- a/x/stakeibc/keeper/reward_converter_test.go +++ b/x/stakeibc/keeper/reward_converter_test.go @@ -11,6 +11,7 @@ import ( transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ibctesting "github.com/cosmos/ibc-go/v7/testing" + "github.com/Stride-Labs/stride/v19/utils" epochtypes "github.com/Stride-Labs/stride/v19/x/epochs/types" icqtypes "github.com/Stride-Labs/stride/v19/x/interchainquery/types" "github.com/Stride-Labs/stride/v19/x/stakeibc/keeper" @@ -34,6 +35,549 @@ type TransferRewardHostToTradeTestCase struct { PortID string } +// -------------------------------------------------------------- +// CalculateRewardsSplitBeforeRebate +// -------------------------------------------------------------- + +func (s *KeeperTestSuite) TestCalculateRewardsSplitBeforeRebate() { + testCases := []struct { + name string + communityPoolLiquidStake sdkmath.Int + totalStTokenSupply sdkmath.Int + rewardAmount sdkmath.Int + strideFee uint64 + rebateRate sdk.Dec + expectedRebateAmount sdkmath.Int + expectedRemainingAmount sdkmath.Int + expectedError string + }{ + { + // 10 CP Liquid Stake, 100 TVL => 10% contribution + // 1000 rewards, 10% stride fee => 100 total fees + // 100 total fees * 10% contribution * 50% rebate + // => 5 rebate, 995 remaining + name: "case 1", + communityPoolLiquidStake: sdkmath.NewInt(10), + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(1000), + strideFee: 10, + rebateRate: sdk.MustNewDecFromStr("0.5"), + + expectedRebateAmount: sdkmath.NewInt(5), + expectedRemainingAmount: sdkmath.NewInt(995), + }, + { + // (Example #1 but with a 2x bigger liquid stake) + // 20 CP Liquid Stake, 100 TVL => 20% contribution + // 1000 rewards, 10% stride fee => 100 total fees + // 100 total fees * 20% contribution * 50% rebate + // => 10 rebate, 990 remaining + name: "case 2", + communityPoolLiquidStake: sdkmath.NewInt(20), + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(1000), + strideFee: 10, + rebateRate: sdk.MustNewDecFromStr("0.5"), + + expectedRebateAmount: sdkmath.NewInt(10), + expectedRemainingAmount: sdkmath.NewInt(990), + }, + { + // (Example #1 but with a 2x larger TVL) + // 10 CP Liquid Stake, 200 TVL => 5% contribution + // 1000 rewards, 10% stride fee => 100 total fees + // 100 total fees * 5% contribution * 50% rebate + // => 2.5 rebate (truncated to 2), 998 remaining + name: "case 3", + communityPoolLiquidStake: sdkmath.NewInt(10), + totalStTokenSupply: sdkmath.NewInt(200), + rewardAmount: sdkmath.NewInt(1000), + strideFee: 10, + rebateRate: sdk.MustNewDecFromStr("0.5"), + + expectedRebateAmount: sdkmath.NewInt(2), + expectedRemainingAmount: sdkmath.NewInt(998), + }, + { + // (Example #1 but with a 2x larger fee) + // 10 CP Liquid Stake, 100 TVL => 10% contribution + // 1000 rewards, 20% stride fee => 200 total fees + // 200 total fees * 10% contribution * 50% rebate + // => 10 rebate, 990 remaining + name: "case 4", + communityPoolLiquidStake: sdkmath.NewInt(10), + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(1000), + strideFee: 20, + rebateRate: sdk.MustNewDecFromStr("0.5"), + + expectedRebateAmount: sdkmath.NewInt(10), + expectedRemainingAmount: sdkmath.NewInt(990), + }, + { + // (Example #1 but with a smaller rebate) + // 10 CP Liquid Stake, 100 TVL => 10% contribution + // 1000 rewards, 10% stride fee => 100 total fees + // 100 total fees * 10% contribution * 20% rebate + // => 2 rebate, 998 remaining + name: "case 5", + communityPoolLiquidStake: sdkmath.NewInt(10), + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(1000), + strideFee: 10, + rebateRate: sdk.MustNewDecFromStr("0.2"), + + expectedRebateAmount: sdkmath.NewInt(2), + expectedRemainingAmount: sdkmath.NewInt(998), + }, + { + // (Example #1 but with a larger rebate) + // 10 CP Liquid Stake, 100 TVL => 10% contribution + // 1000 rewards, 10% stride fee => 100 total fees + // 100 total fees * 10% contribution * 79% rebate + // => 7.9 rebate (truncated to 7), 993 remaining + name: "case 6", + communityPoolLiquidStake: sdkmath.NewInt(10), + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(1000), + strideFee: 10, + rebateRate: sdk.MustNewDecFromStr("0.79"), + + expectedRebateAmount: sdkmath.NewInt(7), + expectedRemainingAmount: sdkmath.NewInt(993), + }, + { + // No rebate - all should be included as "remaining" + name: "nil rebate", + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(1000), + strideFee: 10, + + expectedRebateAmount: sdkmath.NewInt(0), + expectedRemainingAmount: sdkmath.NewInt(1000), + }, + { + // 0% rebate - all should included as "remaining" + name: "zero rebate", + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(1000), + strideFee: 10, + rebateRate: sdk.ZeroDec(), + + expectedRebateAmount: sdkmath.NewInt(0), + expectedRemainingAmount: sdkmath.NewInt(1000), + }, + { + // 100% rebate + // 10 CP Liquid Stake, 100 TVL => 10% contribution + // 1000 rewards, 10% stride fee => 100 total fees + // 100 total fees * 10% contribution * 100% rebate + // => 10 rebate, 990 remaining + name: "full rebate", + communityPoolLiquidStake: sdkmath.NewInt(10), + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(1000), + strideFee: 10, + rebateRate: sdk.OneDec(), + + expectedRebateAmount: sdkmath.NewInt(10), + expectedRemainingAmount: sdkmath.NewInt(990), + }, + { + // Liquid staked amount 0 + // Effectively the same as no rebate + name: "zero liquid staked", + communityPoolLiquidStake: sdkmath.NewInt(0), + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(1000), + strideFee: 10, + rebateRate: sdk.MustNewDecFromStr("0.50"), // ignored since 0 LS'd + + expectedRebateAmount: sdkmath.NewInt(0), + expectedRemainingAmount: sdkmath.NewInt(1000), + }, + { + // Liquid stake represents all of TVL + // Community pool liquid stake represents full TVL + // 100 CP Liquid Stake, 100 TVL => 100% contribution + // 1000 rewards, 10% stride fee => 100 total fees + // 100 total fees * 100% contribution * 50% rebate + // => 50 rebate, 950 reinvest + name: "liquid stake represents full TVL", + communityPoolLiquidStake: sdkmath.NewInt(100), + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(1000), + strideFee: 10, + rebateRate: sdk.MustNewDecFromStr("0.50"), + + expectedRebateAmount: sdkmath.NewInt(50), + expectedRemainingAmount: sdkmath.NewInt(950), + }, + { + // 100% contribution, 100% rebate + // Community pool gets all fees (100), 900 remaining + name: "liquid stake represents full TVL and full rebate", + communityPoolLiquidStake: sdkmath.NewInt(100), + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(1000), + strideFee: 10, + rebateRate: sdk.OneDec(), + + expectedRebateAmount: sdkmath.NewInt(100), + expectedRemainingAmount: sdkmath.NewInt(900), + }, + { + // No tvl - should error + name: "no tvl", + communityPoolLiquidStake: sdk.NewInt(10), + totalStTokenSupply: sdkmath.NewInt(0), + rewardAmount: sdkmath.NewInt(1000), + strideFee: 10, + rebateRate: sdk.MustNewDecFromStr("0.5"), + + expectedError: "unable to calculate rebate amount", + }, + { + // Liquid staked amount is greater than the TVL - should error + name: "liquid staked more than tvl", + communityPoolLiquidStake: sdk.NewInt(1001), + totalStTokenSupply: sdkmath.NewInt(1000), + rewardAmount: sdkmath.NewInt(100), + strideFee: 10, + rebateRate: sdk.MustNewDecFromStr("0.5"), + + expectedError: "community pool liquid staked amount greater than total delegations", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + s.SetupTest() // resets supply + + // Build out the host zone - only add the rebate struct if one of the rebate fields was provided + hostZone := types.HostZone{ + ChainId: chainId, + HostDenom: HostDenom, + } + if !tc.communityPoolLiquidStake.IsNil() { + hostZone.CommunityPoolRebate = &types.CommunityPoolRebate{ + RebateRate: tc.rebateRate, + LiquidStakedStTokenAmount: tc.communityPoolLiquidStake, + } + } + + // Store the fee as a param + params := types.DefaultParams() + params.StrideCommission = tc.strideFee + s.App.StakeibcKeeper.SetParams(s.Ctx, params) + + // Mint stTokens to populate the supply + stCoin := sdk.NewCoin(utils.StAssetDenomFromHostZoneDenom(HostDenom), tc.totalStTokenSupply) + s.FundAccount(s.TestAccs[0], stCoin) + + // Call the tested function to get the expected amounts + actualRebateAmount, actualRemainingAmount, actualError := s.App.StakeibcKeeper.CalculateRewardsSplitBeforeRebate( + s.Ctx, + hostZone, + tc.rewardAmount, + ) + + // Confirm the amounts and error + if tc.expectedError != "" { + s.Require().ErrorContains(actualError, tc.expectedError, "error expected") + } else { + s.Require().Equal(tc.expectedRebateAmount.Int64(), actualRebateAmount.Int64(), "rebate amount") + s.Require().Equal(tc.expectedRemainingAmount.Int64(), actualRemainingAmount.Int64(), "remaining amount") + } + }) + } +} + +// -------------------------------------------------------------- +// CalculateRewardsSplitAfterRebate +// -------------------------------------------------------------- + +func (s *KeeperTestSuite) TestCalculateRewardsSplitAfterRebate() { + testCases := []struct { + name string + communityPoolLiquidStake sdkmath.Int + totalStTokenSupply sdkmath.Int + rewardAmount sdkmath.Int + strideFee uint64 + rebateRate sdk.Dec + expectedStrideFeeAmount sdkmath.Int + expectedReinvestAmount sdkmath.Int + expectedError string + }{ + { + // 10 CP Liquid Stake, 100 TVL => 10% contribution + // 1000 original rewards, 10% stride fee => 100 total fees + // 100 total fees * 10% contribution * 50% rebate => 5 rebate + // + // 1000 original rewards - 5 rebate = 995 current rewards (test input) + // 1000 original rewards - 100 total fees = 900 reinvest + // 100 total fees - 5 rebate = 95 stride fees + name: "case 1", + communityPoolLiquidStake: sdkmath.NewInt(10), + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(995), + strideFee: 10, + rebateRate: sdk.MustNewDecFromStr("0.5"), + + expectedStrideFeeAmount: sdkmath.NewInt(95), + expectedReinvestAmount: sdkmath.NewInt(900), + }, + { + // (Example #1 but with a 2x bigger liquid stake) + // 20 CP Liquid Stake, 100 TVL => 20% contribution + // 1000 original rewards, 10% stride fee => 100 total fees + // 100 total fees * 20% contribution * 50% rebate = 10 rebate + // + // 1000 original rewards - 10 rebate = 990 current rewards (test input) + // 1000 original rewards - 100 total fees = 900 reinvest + // 100 total fees - 10 rebate = 90 stride fees + name: "case 2", + communityPoolLiquidStake: sdkmath.NewInt(20), + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(990), + strideFee: 10, + rebateRate: sdk.MustNewDecFromStr("0.5"), + + expectedStrideFeeAmount: sdkmath.NewInt(90), + expectedReinvestAmount: sdkmath.NewInt(900), + }, + { + // (Example #1 but with a 2x larger TVL) + // 10 CP Liquid Stake, 200 TVL => 5% contribution + // 1000 original rewards, 10% stride fee => 100 total fees + // 100 total fees * 5% contribution * 50% rebate = 2.5 rebated (truncated to 2) + // + // 1000 original rewards - 2 rebate = 998 current rewards (test input) + // 1000 original rewards - 100 total fees = 900 reinvest + // 100 total fees - 2 rebate = 98 stride fees + name: "case 3", + communityPoolLiquidStake: sdkmath.NewInt(10), + totalStTokenSupply: sdkmath.NewInt(200), + rewardAmount: sdkmath.NewInt(998), + strideFee: 10, + rebateRate: sdk.MustNewDecFromStr("0.5"), + + expectedStrideFeeAmount: sdkmath.NewInt(98), + expectedReinvestAmount: sdkmath.NewInt(900), + }, + { + // (Example #1 but with a 2x larger fee) + // 10 CP Liquid Stake, 100 TVL => 10% contribution + // 1000 original rewards, 20% stride fee => 200 total fees + // 200 total fees * 10% contribution * 50% rebate => 10 rebate + // + // 1000 original rewards - 10 rebate = 990 current rewards (test input) + // 1000 original rewards - 200 total fees = 800 reinvest + // 200 total fees - 10 rebate = 190 stride fees + name: "case 4", + communityPoolLiquidStake: sdkmath.NewInt(10), + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(990), + strideFee: 20, + rebateRate: sdk.MustNewDecFromStr("0.5"), + + expectedStrideFeeAmount: sdkmath.NewInt(190), + expectedReinvestAmount: sdkmath.NewInt(800), + }, + { + // (Example #1 but with a smaller rebate) + // 10 CP Liquid Stake, 100 TVL => 10% contribution + // 1000 original rewards, 10% stride fee => 100 total fees + // 100 total fees * 10% contribution * 20% rebate => 2 rebate + // + // 1000 original rewards - 2 rebate = 998 current rewards (test input) + // 1000 original rewards - 100 total fees = 900 reinvest + // 100 total fees - 2 rebate = 98 stride fees + name: "case 5", + communityPoolLiquidStake: sdkmath.NewInt(10), + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(998), + strideFee: 10, + rebateRate: sdk.MustNewDecFromStr("0.2"), + + expectedStrideFeeAmount: sdkmath.NewInt(98), + expectedReinvestAmount: sdkmath.NewInt(900), + }, + { + // (Example #1 but with a larger rebate) + // 10 CP Liquid Stake, 100 TVL => 10% contribution + // 1000 original rewards, 10% stride fee => 100 total fees + // 100 total fees * 10% contribution * 79% rebate => 7.9 rebate (truncated to 7) + // + // 1000 original rewards - 7 rebate = 993 current rewards (test input) + // 1000 original rewards - 100 total fees = 900 reinvest + // 100 total fees - 7 rebate = 93 stride fees + name: "case 6", + communityPoolLiquidStake: sdkmath.NewInt(10), + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(993), + strideFee: 10, + rebateRate: sdk.MustNewDecFromStr("0.79"), + + expectedStrideFeeAmount: sdkmath.NewInt(93), + expectedReinvestAmount: sdkmath.NewInt(900), + }, + { + // No rebate - all fees go to stride + // 10% fees off 1000 rewards = 100 stride fees, 900 reinvest + name: "nil rebate", + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(1000), + strideFee: 10, + + expectedStrideFeeAmount: sdkmath.NewInt(100), + expectedReinvestAmount: sdkmath.NewInt(900), + }, + { + // 0% rebate - all fees go to stride + // 10% fees off 1000 rewards = 100 stride fees, 900 reinvest + name: "zero rebate", + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(1000), + strideFee: 10, + rebateRate: sdk.ZeroDec(), + + expectedStrideFeeAmount: sdkmath.NewInt(100), + expectedReinvestAmount: sdkmath.NewInt(900), + }, + { + // 100% rebate + // 10 CP Liquid Stake, 100 TVL => 10% contribution + // 1000 original rewards, 10% stride fee => 100 total fees + // 100 total fees * 10% contribution * 100% rebate => 10 rebate + // + // 1000 original rewards - 10 rebate = 990 current rewards (test input) + // 1000 original rewards - 100 total fees = 900 reinvest + // 100 total fees - 10 rebate = 90 stride fees + name: "full rebate", + communityPoolLiquidStake: sdkmath.NewInt(10), + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(990), + strideFee: 10, + rebateRate: sdk.OneDec(), + + expectedStrideFeeAmount: sdkmath.NewInt(90), + expectedReinvestAmount: sdkmath.NewInt(900), + }, + { + // Liquid staked amount 0 - effectively the same as no rebate + // 10% fees off 1000 rewards = 100 stride fees, 900 reinvest + name: "zero liquid staked", + communityPoolLiquidStake: sdkmath.NewInt(0), + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(1000), + strideFee: 10, + rebateRate: sdk.MustNewDecFromStr("0.50"), // ignored since 0 LS'd + + expectedStrideFeeAmount: sdkmath.NewInt(100), + expectedReinvestAmount: sdkmath.NewInt(900), + }, + { + // Liquid stake represents all of TVL + // Community pool liquid stake represents full TVL + // 100 CP Liquid Stake, 100 TVL => 100% contribution + // 1000 original rewards, 10% stride fee => 100 total fees + // 100 total fees * 100% contribution * 50% rebate => 50 rebate + // + // 1000 original rewards - 50 rebate = 950 current rewards (test input) + // 1000 original rewards - 100 total fees = 900 reinvest + // 100 total fees - 50 rebate = 50 stride fees + name: "liquid stake represents full TVL", + communityPoolLiquidStake: sdkmath.NewInt(100), + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(950), + strideFee: 10, + rebateRate: sdk.MustNewDecFromStr("0.50"), + + expectedStrideFeeAmount: sdkmath.NewInt(50), + expectedReinvestAmount: sdkmath.NewInt(900), + }, + { + // 100% contribution, 100% rebate + // Community pool gets all fees + // 1000 original rewards => 100 rebate, 900 reinvest (test input) + name: "liquid stake represents full TVL and full rebate", + communityPoolLiquidStake: sdkmath.NewInt(100), + totalStTokenSupply: sdkmath.NewInt(100), + rewardAmount: sdkmath.NewInt(900), + strideFee: 10, + rebateRate: sdk.OneDec(), + + expectedStrideFeeAmount: sdkmath.NewInt(0), + expectedReinvestAmount: sdkmath.NewInt(900), + }, + { + // No tvl - should error + name: "no tvl", + communityPoolLiquidStake: sdk.NewInt(10), + totalStTokenSupply: sdkmath.NewInt(0), + rewardAmount: sdkmath.NewInt(1000), + strideFee: 10, + rebateRate: sdk.MustNewDecFromStr("0.5"), + + expectedError: "unable to calculate rebate amount", + }, + { + // Liquid staked amount is greater than the TVL - should error + name: "liquid staked more than tvl", + communityPoolLiquidStake: sdk.NewInt(1001), + totalStTokenSupply: sdkmath.NewInt(1000), + rewardAmount: sdkmath.NewInt(100), + strideFee: 10, + rebateRate: sdk.MustNewDecFromStr("0.5"), + + expectedError: "community pool liquid staked amount greater than total delegations", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + s.SetupTest() // resets supply + + // Build out the host zone - only add the rebate struct if one of the rebate fields was provided + hostZone := types.HostZone{ + ChainId: chainId, + HostDenom: HostDenom, + } + if !tc.communityPoolLiquidStake.IsNil() { + hostZone.CommunityPoolRebate = &types.CommunityPoolRebate{ + RebateRate: tc.rebateRate, + LiquidStakedStTokenAmount: tc.communityPoolLiquidStake, + } + } + + // Store the fee as a param + params := types.DefaultParams() + params.StrideCommission = tc.strideFee + s.App.StakeibcKeeper.SetParams(s.Ctx, params) + + // Mint stTokens to populate the supply + stCoin := sdk.NewCoin(utils.StAssetDenomFromHostZoneDenom(HostDenom), tc.totalStTokenSupply) + s.FundAccount(s.TestAccs[0], stCoin) + + // Call the tested function to get the expected amounts + actualStrideFeeAmount, actualReinvestAmount, actualError := s.App.StakeibcKeeper.CalculateRewardsSplitAfterRebate( + s.Ctx, + hostZone, + tc.rewardAmount, + ) + + // Confirm the amounts + if tc.expectedError != "" { + s.Require().ErrorContains(actualError, tc.expectedError, "error expected") + } else { + s.Require().Equal(tc.expectedStrideFeeAmount.Int64(), actualStrideFeeAmount.Int64(), "stride fee amount") + s.Require().Equal(tc.expectedReinvestAmount.Int64(), actualReinvestAmount.Int64(), "reinvest amount") + } + }) + } +} + // -------------------------------------------------------------- // BuildTradeAuthzMsg // -------------------------------------------------------------- diff --git a/x/stakeibc/types/errors.go b/x/stakeibc/types/errors.go index 3d90bfb072..9bbbf2df35 100644 --- a/x/stakeibc/types/errors.go +++ b/x/stakeibc/types/errors.go @@ -65,4 +65,6 @@ var ( ErrClientStateNotTendermint = errorsmod.Register(ModuleName, 1558, "Client state not tendermint") ErrTradeRouteNotFound = errorsmod.Register(ModuleName, 1559, "trade route not found") ErrValidatorExceedsWeightCap = errorsmod.Register(ModuleName, 1560, "validator exceeds weight cap") + ErrFeeSplitInvariantFailed = errorsmod.Register(ModuleName, 1561, "failed to calculate fee split") + ErrFailedToRegisterRebate = errorsmod.Register(ModuleName, 1562, "failed to register rebate") ) diff --git a/x/stakeibc/types/host_zone.go b/x/stakeibc/types/host_zone.go index e39917b508..152935df47 100644 --- a/x/stakeibc/types/host_zone.go +++ b/x/stakeibc/types/host_zone.go @@ -28,7 +28,7 @@ func (h HostZone) SafelyGetCommunityPoolRebate() (rebate CommunityPoolRebate, ex if h.CommunityPoolRebate == nil { return CommunityPoolRebate{}, false } - if h.CommunityPoolRebate.LiquidStakeAmount.IsNil() || h.CommunityPoolRebate.RebatePercentage.IsNil() { + if h.CommunityPoolRebate.LiquidStakedStTokenAmount.IsNil() || h.CommunityPoolRebate.RebateRate.IsNil() { return CommunityPoolRebate{}, false } return *h.CommunityPoolRebate, true diff --git a/x/stakeibc/types/host_zone.pb.go b/x/stakeibc/types/host_zone.pb.go index 27fdf5b6a8..f4ba2eb688 100644 --- a/x/stakeibc/types/host_zone.pb.go +++ b/x/stakeibc/types/host_zone.pb.go @@ -26,10 +26,12 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // CommunityPoolRebate stores the size of the community pool liquid stake -// and the rebate percentage +// (denominated in stTokens) and the rebate rate as a decimal type CommunityPoolRebate struct { - RebatePercentage github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,1,opt,name=rebate_percentage,json=rebatePercentage,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"rebate_percentage"` - LiquidStakeAmount github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=liquid_stake_amount,json=liquidStakeAmount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"liquid_stake_amount"` + // Rebate percentage as a decimal (e.g. 0.2 for 20%) + RebateRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,1,opt,name=rebate_rate,json=rebateRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"rebate_rate"` + // Number of stTokens received from the community pool liquid stake + LiquidStakedStTokenAmount github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=liquid_staked_st_token_amount,json=liquidStakedStTokenAmount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"liquid_staked_st_token_amount"` } func (m *CommunityPoolRebate) Reset() { *m = CommunityPoolRebate{} } @@ -65,36 +67,78 @@ func (m *CommunityPoolRebate) XXX_DiscardUnknown() { var xxx_messageInfo_CommunityPoolRebate proto.InternalMessageInfo +// Core data structure to track liquid staking zones type HostZone struct { - ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` - Bech32Prefix string `protobuf:"bytes,17,opt,name=bech32prefix,proto3" json:"bech32prefix,omitempty"` - ConnectionId string `protobuf:"bytes,2,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"` + // Chain ID of the host zone + ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // Bech32 prefix of host zone's address + Bech32Prefix string `protobuf:"bytes,17,opt,name=bech32prefix,proto3" json:"bech32prefix,omitempty"` + // ConnectionID from Stride to the host zone (ID is on the stride side) + ConnectionId string `protobuf:"bytes,2,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"` + // Transfer Channel ID from Stride to the host zone (ID is on the stride side) TransferChannelId string `protobuf:"bytes,12,opt,name=transfer_channel_id,json=transferChannelId,proto3" json:"transfer_channel_id,omitempty"` - // ibc denom on stride + // ibc denom of the host zone's native token on stride IbcDenom string `protobuf:"bytes,8,opt,name=ibc_denom,json=ibcDenom,proto3" json:"ibc_denom,omitempty"` // native denom on host zone - HostDenom string `protobuf:"bytes,9,opt,name=host_denom,json=hostDenom,proto3" json:"host_denom,omitempty"` - UnbondingPeriod uint64 `protobuf:"varint,26,opt,name=unbonding_period,json=unbondingPeriod,proto3" json:"unbonding_period,omitempty"` - Validators []*Validator `protobuf:"bytes,3,rep,name=validators,proto3" json:"validators,omitempty"` - DepositAddress string `protobuf:"bytes,18,opt,name=deposit_address,json=depositAddress,proto3" json:"deposit_address,omitempty"` - WithdrawalIcaAddress string `protobuf:"bytes,22,opt,name=withdrawal_ica_address,json=withdrawalIcaAddress,proto3" json:"withdrawal_ica_address,omitempty"` - FeeIcaAddress string `protobuf:"bytes,23,opt,name=fee_ica_address,json=feeIcaAddress,proto3" json:"fee_ica_address,omitempty"` - DelegationIcaAddress string `protobuf:"bytes,24,opt,name=delegation_ica_address,json=delegationIcaAddress,proto3" json:"delegation_ica_address,omitempty"` - RedemptionIcaAddress string `protobuf:"bytes,25,opt,name=redemption_ica_address,json=redemptionIcaAddress,proto3" json:"redemption_ica_address,omitempty"` - CommunityPoolDepositIcaAddress string `protobuf:"bytes,30,opt,name=community_pool_deposit_ica_address,json=communityPoolDepositIcaAddress,proto3" json:"community_pool_deposit_ica_address,omitempty"` - CommunityPoolReturnIcaAddress string `protobuf:"bytes,31,opt,name=community_pool_return_ica_address,json=communityPoolReturnIcaAddress,proto3" json:"community_pool_return_ica_address,omitempty"` - CommunityPoolStakeHoldingAddress string `protobuf:"bytes,32,opt,name=community_pool_stake_holding_address,json=communityPoolStakeHoldingAddress,proto3" json:"community_pool_stake_holding_address,omitempty"` - CommunityPoolRedeemHoldingAddress string `protobuf:"bytes,33,opt,name=community_pool_redeem_holding_address,json=communityPoolRedeemHoldingAddress,proto3" json:"community_pool_redeem_holding_address,omitempty"` - TotalDelegations github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,13,opt,name=total_delegations,json=totalDelegations,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"total_delegations"` - LastRedemptionRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,10,opt,name=last_redemption_rate,json=lastRedemptionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"last_redemption_rate"` - RedemptionRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,11,opt,name=redemption_rate,json=redemptionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"redemption_rate"` - MinRedemptionRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,20,opt,name=min_redemption_rate,json=minRedemptionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"min_redemption_rate"` - MaxRedemptionRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,21,opt,name=max_redemption_rate,json=maxRedemptionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"max_redemption_rate"` - MinInnerRedemptionRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,28,opt,name=min_inner_redemption_rate,json=minInnerRedemptionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"min_inner_redemption_rate"` - MaxInnerRedemptionRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,29,opt,name=max_inner_redemption_rate,json=maxInnerRedemptionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"max_inner_redemption_rate"` - CommunityPoolRebate *CommunityPoolRebate `protobuf:"bytes,34,opt,name=community_pool_rebate,json=communityPoolRebate,proto3" json:"community_pool_rebate,omitempty"` - LsmLiquidStakeEnabled bool `protobuf:"varint,27,opt,name=lsm_liquid_stake_enabled,json=lsmLiquidStakeEnabled,proto3" json:"lsm_liquid_stake_enabled,omitempty"` - Halted bool `protobuf:"varint,19,opt,name=halted,proto3" json:"halted,omitempty"` + HostDenom string `protobuf:"bytes,9,opt,name=host_denom,json=hostDenom,proto3" json:"host_denom,omitempty"` + // The unbonding period in days (e.g. 21) + UnbondingPeriod uint64 `protobuf:"varint,26,opt,name=unbonding_period,json=unbondingPeriod,proto3" json:"unbonding_period,omitempty"` + // List of validators that are delegated to + Validators []*Validator `protobuf:"bytes,3,rep,name=validators,proto3" json:"validators,omitempty"` + // Address that custodies native tokens during a liquid stake + DepositAddress string `protobuf:"bytes,18,opt,name=deposit_address,json=depositAddress,proto3" json:"deposit_address,omitempty"` + // ICA Address on the host zone responsible for collecting rewards + WithdrawalIcaAddress string `protobuf:"bytes,22,opt,name=withdrawal_ica_address,json=withdrawalIcaAddress,proto3" json:"withdrawal_ica_address,omitempty"` + // ICA Address on the host zone responsible for commission + FeeIcaAddress string `protobuf:"bytes,23,opt,name=fee_ica_address,json=feeIcaAddress,proto3" json:"fee_ica_address,omitempty"` + // ICA Address on the host zone responsible for staking and unstaking + DelegationIcaAddress string `protobuf:"bytes,24,opt,name=delegation_ica_address,json=delegationIcaAddress,proto3" json:"delegation_ica_address,omitempty"` + // ICA Address that receives unstaked tokens after they've finished unbonding + RedemptionIcaAddress string `protobuf:"bytes,25,opt,name=redemption_ica_address,json=redemptionIcaAddress,proto3" json:"redemption_ica_address,omitempty"` + // ICA Address that receives tokens from a community pool to liquid stake or + // redeem In the case of a liquid stake, the community pool deposits native + // tokens In the case of a redemption, the community pool deposits stTokens + CommunityPoolDepositIcaAddress string `protobuf:"bytes,30,opt,name=community_pool_deposit_ica_address,json=communityPoolDepositIcaAddress,proto3" json:"community_pool_deposit_ica_address,omitempty"` + // ICA Address that distributes tokens back to the community pool during a + // community pool liquid stake or redeem In the case of a liquid stake, the + // return address sends back stTokens In the case of a redemption, the return + // address sends back native tokens + CommunityPoolReturnIcaAddress string `protobuf:"bytes,31,opt,name=community_pool_return_ica_address,json=communityPoolReturnIcaAddress,proto3" json:"community_pool_return_ica_address,omitempty"` + // Module account on Stride that receives native tokens from the deposit ICA + // and liquid stakes them + CommunityPoolStakeHoldingAddress string `protobuf:"bytes,32,opt,name=community_pool_stake_holding_address,json=communityPoolStakeHoldingAddress,proto3" json:"community_pool_stake_holding_address,omitempty"` + // Module account on Stride that receives stTokens from the deposit ICA and + // redeems them + CommunityPoolRedeemHoldingAddress string `protobuf:"bytes,33,opt,name=community_pool_redeem_holding_address,json=communityPoolRedeemHoldingAddress,proto3" json:"community_pool_redeem_holding_address,omitempty"` + // Optional community pool address to send tokens to after a community pool + // liquid stake or redemption If this address is empty, the tokens are sent to + // the main community pool + CommunityPoolTreasuryAddress string `protobuf:"bytes,35,opt,name=community_pool_treasury_address,json=communityPoolTreasuryAddress,proto3" json:"community_pool_treasury_address,omitempty"` + // The total delegated balance on the host zone + TotalDelegations github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,13,opt,name=total_delegations,json=totalDelegations,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"total_delegations"` + // The redemption rate from the previous epoch + LastRedemptionRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,10,opt,name=last_redemption_rate,json=lastRedemptionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"last_redemption_rate"` + // The current redemption rate + RedemptionRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,11,opt,name=redemption_rate,json=redemptionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"redemption_rate"` + // The min outer redemption rate bound - controlled only be governance + // The min inner bound cannot exceed this bound + MinRedemptionRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,20,opt,name=min_redemption_rate,json=minRedemptionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"min_redemption_rate"` + // The max outer redemption rate bound - controlled only be governance + // The max inner bound cannot exceed this bound + MaxRedemptionRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,21,opt,name=max_redemption_rate,json=maxRedemptionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"max_redemption_rate"` + // The min minner redemption rate bound - controlled by the admin + // If the redemption rate exceeds this bound, the host zone is halted + MinInnerRedemptionRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,28,opt,name=min_inner_redemption_rate,json=minInnerRedemptionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"min_inner_redemption_rate"` + // The max minner redemption rate bound - controlled by the admin + // If the redemption rate exceeds this bound, the host zone is halted + MaxInnerRedemptionRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,29,opt,name=max_inner_redemption_rate,json=maxInnerRedemptionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"max_inner_redemption_rate"` + // An optional fee rebate + // If there is no rebate for the host zone, this will be nil + CommunityPoolRebate *CommunityPoolRebate `protobuf:"bytes,34,opt,name=community_pool_rebate,json=communityPoolRebate,proto3" json:"community_pool_rebate,omitempty"` + // A boolean indicating whether the chain has LSM enabled + LsmLiquidStakeEnabled bool `protobuf:"varint,27,opt,name=lsm_liquid_stake_enabled,json=lsmLiquidStakeEnabled,proto3" json:"lsm_liquid_stake_enabled,omitempty"` + // A boolean indicating whether the chain is currently halted + Halted bool `protobuf:"varint,19,opt,name=halted,proto3" json:"halted,omitempty"` } func (m *HostZone) Reset() { *m = HostZone{} } @@ -249,6 +293,13 @@ func (m *HostZone) GetCommunityPoolRedeemHoldingAddress() string { return "" } +func (m *HostZone) GetCommunityPoolTreasuryAddress() string { + if m != nil { + return m.CommunityPoolTreasuryAddress + } + return "" +} + func (m *HostZone) GetCommunityPoolRebate() *CommunityPoolRebate { if m != nil { return m.CommunityPoolRebate @@ -278,65 +329,67 @@ func init() { func init() { proto.RegisterFile("stride/stakeibc/host_zone.proto", fileDescriptor_f81bf5b42c61245a) } var fileDescriptor_f81bf5b42c61245a = []byte{ - // 922 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x96, 0xcf, 0x6e, 0xdb, 0x36, - 0x18, 0xc0, 0xe3, 0xd6, 0x4d, 0x14, 0xa6, 0x89, 0x65, 0xd9, 0xf1, 0x94, 0x74, 0x71, 0x1c, 0xaf, - 0x1b, 0xbc, 0x43, 0x6c, 0x2c, 0x3d, 0x0c, 0x1b, 0x76, 0x58, 0xda, 0x0c, 0xa8, 0x8d, 0xa0, 0x08, - 0x14, 0x60, 0x18, 0x5a, 0x60, 0x02, 0x45, 0x7e, 0xb1, 0xb9, 0x4a, 0xa4, 0x27, 0xd2, 0x8d, 0xbb, - 0xa7, 0xd8, 0x8b, 0xec, 0xd6, 0x87, 0xe8, 0xb1, 0xc8, 0x69, 0xd8, 0xa1, 0x18, 0x92, 0x17, 0x19, - 0x44, 0xfa, 0x8f, 0x6c, 0x65, 0x30, 0x52, 0xf8, 0x64, 0x91, 0xdf, 0xc7, 0xdf, 0xcf, 0x9f, 0xf8, - 0x47, 0x44, 0xfb, 0x52, 0xc5, 0x8c, 0x42, 0x4b, 0x2a, 0xfc, 0x1a, 0x58, 0x40, 0x5a, 0x3d, 0x21, - 0x95, 0xff, 0x87, 0xe0, 0xd0, 0xec, 0xc7, 0x42, 0x09, 0xa7, 0x60, 0x12, 0x9a, 0xe3, 0x84, 0xdd, - 0xcc, 0x88, 0x37, 0x38, 0x64, 0x14, 0x2b, 0x11, 0x9b, 0x11, 0xbb, 0xe5, 0xae, 0xe8, 0x0a, 0xfd, - 0xd8, 0x4a, 0x9e, 0x46, 0xbd, 0x3b, 0x44, 0xc8, 0x48, 0x48, 0xdf, 0x04, 0x4c, 0xc3, 0x84, 0xea, - 0x57, 0x39, 0x54, 0x7a, 0x26, 0xa2, 0x68, 0xc0, 0x99, 0x7a, 0x7b, 0x26, 0x44, 0xe8, 0x41, 0x80, - 0x15, 0x38, 0xaf, 0x50, 0x31, 0xd6, 0x4f, 0x7e, 0x1f, 0x62, 0x02, 0x5c, 0xe1, 0x2e, 0xb8, 0xb9, - 0x5a, 0xae, 0xb1, 0xfe, 0xb4, 0xf9, 0xfe, 0xe3, 0xfe, 0xca, 0x3f, 0x1f, 0xf7, 0xbf, 0xea, 0x32, - 0xd5, 0x1b, 0x04, 0x4d, 0x22, 0xa2, 0x11, 0x73, 0xf4, 0x73, 0x28, 0xe9, 0xeb, 0x96, 0x7a, 0xdb, - 0x07, 0xd9, 0x3c, 0x01, 0xe2, 0xd9, 0x06, 0x74, 0x36, 0xe1, 0x38, 0xbf, 0xa2, 0x52, 0xc8, 0x7e, - 0x1f, 0x30, 0xea, 0xeb, 0x42, 0x7c, 0x1c, 0x89, 0x01, 0x57, 0xee, 0xbd, 0x3b, 0xe3, 0xdb, 0x5c, - 0x79, 0x45, 0x83, 0x3a, 0x4f, 0x48, 0xc7, 0x1a, 0x54, 0xff, 0xcb, 0x46, 0xd6, 0x73, 0x21, 0xd5, - 0x4b, 0xc1, 0xc1, 0xd9, 0x41, 0x16, 0xe9, 0x61, 0xc6, 0x7d, 0x46, 0x4d, 0x01, 0xde, 0x9a, 0x6e, - 0xb7, 0xa9, 0x53, 0x47, 0x0f, 0x03, 0x20, 0xbd, 0x27, 0x47, 0xfd, 0x18, 0x2e, 0xd8, 0xd0, 0x2d, - 0xea, 0xf0, 0x4c, 0x9f, 0xf3, 0x05, 0xda, 0x24, 0x82, 0x73, 0x20, 0x8a, 0x09, 0xcd, 0xb8, 0x67, - 0x92, 0xa6, 0x9d, 0x6d, 0xea, 0x34, 0x51, 0x49, 0xc5, 0x98, 0xcb, 0x0b, 0x88, 0x7d, 0xd2, 0xc3, - 0x9c, 0x43, 0x98, 0xa4, 0x3e, 0xd4, 0xa9, 0xc5, 0x71, 0xe8, 0x99, 0x89, 0xb4, 0xa9, 0xf3, 0x08, - 0xad, 0xb3, 0x80, 0xf8, 0x14, 0xb8, 0x88, 0x5c, 0x4b, 0x67, 0x59, 0x2c, 0x20, 0x27, 0x49, 0xdb, - 0xd9, 0x43, 0x48, 0x2f, 0x04, 0x13, 0x5d, 0xd7, 0xd1, 0xf5, 0xa4, 0xc7, 0x84, 0xbf, 0x46, 0xf6, - 0x80, 0x07, 0x82, 0x53, 0xc6, 0xbb, 0xc9, 0xe4, 0x30, 0x41, 0xdd, 0xdd, 0x5a, 0xae, 0x91, 0xf7, - 0x0a, 0x93, 0xfe, 0x33, 0xdd, 0xed, 0x7c, 0x8f, 0xd0, 0x64, 0x81, 0x48, 0xf7, 0x7e, 0xed, 0x7e, - 0x63, 0xe3, 0x68, 0xb7, 0x39, 0xb7, 0xa8, 0x9a, 0x3f, 0x8f, 0x53, 0xbc, 0x54, 0xb6, 0x73, 0x8c, - 0x0a, 0x14, 0xfa, 0x42, 0x32, 0xe5, 0x63, 0x4a, 0x63, 0x90, 0xd2, 0x75, 0xf4, 0xfc, 0xb8, 0x57, - 0xef, 0x0e, 0xcb, 0xa3, 0x35, 0x74, 0x6c, 0x22, 0xe7, 0x2a, 0x66, 0xbc, 0xeb, 0x6d, 0x8d, 0x06, - 0x8c, 0x7a, 0x9d, 0x17, 0xa8, 0x72, 0xc9, 0x54, 0x8f, 0xc6, 0xf8, 0x12, 0x87, 0x3e, 0x23, 0x78, - 0x42, 0xaa, 0x2c, 0x20, 0x95, 0xa7, 0xe3, 0xda, 0x04, 0x8f, 0x79, 0x3f, 0xa2, 0xc2, 0x05, 0xc0, - 0x0c, 0xe8, 0xb3, 0x05, 0xa0, 0xcd, 0x0b, 0x80, 0x14, 0xe1, 0x05, 0xaa, 0x50, 0x08, 0xa1, 0x8b, - 0xcd, 0x64, 0xa6, 0x40, 0xee, 0xa2, 0x7f, 0x34, 0x1d, 0x37, 0xcb, 0x8b, 0x81, 0x42, 0xd4, 0xcf, - 0xf0, 0x76, 0x16, 0xf1, 0xa6, 0xe3, 0x52, 0x3c, 0x8a, 0xea, 0x64, 0xbc, 0x19, 0xfd, 0xbe, 0x10, - 0xa1, 0x3f, 0x9e, 0x83, 0x34, 0xbb, 0xba, 0x80, 0x5d, 0x25, 0xe9, 0x0d, 0x7d, 0x62, 0x08, 0x29, - 0x4b, 0x80, 0x0e, 0xe6, 0x2c, 0x31, 0xa8, 0x41, 0x3c, 0x5b, 0xc0, 0xfe, 0x02, 0xc9, 0x1e, 0x99, - 0x3d, 0x35, 0x12, 0x40, 0xca, 0xd1, 0x43, 0x8f, 0xe7, 0x1c, 0x66, 0xab, 0xf7, 0x44, 0xa8, 0x17, - 0xee, 0x58, 0x53, 0x5b, 0xa0, 0xa9, 0xcd, 0x68, 0xf4, 0x26, 0x7f, 0x6e, 0x10, 0x63, 0xd3, 0x6f, - 0xe8, 0xcb, 0x4c, 0x35, 0x14, 0x20, 0xca, 0xa8, 0x0e, 0x16, 0xa8, 0x0e, 0xe6, 0x2a, 0x4a, 0x20, - 0x73, 0xae, 0x57, 0xa8, 0xa8, 0x84, 0xc2, 0xc9, 0xb4, 0x8c, 0x57, 0x83, 0x74, 0x37, 0x3f, 0xe9, - 0xd8, 0xb2, 0x35, 0xe8, 0x64, 0xca, 0x71, 0x38, 0x2a, 0x87, 0x58, 0x2a, 0x3f, 0xb5, 0xa2, 0x62, - 0xac, 0xc0, 0x45, 0x9a, 0xff, 0xc3, 0xdd, 0x4e, 0xdd, 0xab, 0x77, 0x87, 0x68, 0x54, 0x65, 0x72, - 0x06, 0x3b, 0x09, 0xd9, 0x9b, 0x80, 0xbd, 0xe4, 0x88, 0x07, 0x54, 0x98, 0x57, 0x6d, 0x2c, 0x41, - 0xb5, 0x15, 0xcf, 0x6a, 0x42, 0x54, 0x8a, 0x18, 0xcf, 0x54, 0x55, 0x5e, 0x82, 0xaa, 0x18, 0x31, - 0xee, 0x65, 0x6d, 0x78, 0x98, 0xb1, 0x6d, 0x2f, 0xc5, 0x86, 0x87, 0x73, 0xb6, 0x4b, 0xb4, 0x93, - 0xd4, 0xc6, 0x38, 0x87, 0x38, 0xe3, 0xfc, 0x7c, 0x09, 0xce, 0x4a, 0xc4, 0x78, 0x3b, 0xa1, 0xdf, - 0x22, 0xc6, 0xc3, 0xff, 0x11, 0xef, 0x2d, 0x45, 0x8c, 0x87, 0xb7, 0x89, 0x7f, 0x41, 0xdb, 0x99, - 0xdd, 0x96, 0x7c, 0xdd, 0xdd, 0x7a, 0x2d, 0xd7, 0xd8, 0x38, 0x7a, 0x9c, 0xf9, 0xba, 0xdc, 0x72, - 0xb9, 0xf0, 0x4a, 0xe4, 0x96, 0x1b, 0xc7, 0xb7, 0xc8, 0x0d, 0x65, 0xe4, 0xcf, 0x5c, 0x0c, 0x80, - 0xe3, 0x20, 0x04, 0xea, 0x3e, 0xaa, 0xe5, 0x1a, 0x96, 0xb7, 0x1d, 0xca, 0xe8, 0x74, 0xfa, 0xb1, - 0xff, 0xc9, 0x04, 0x9d, 0x0a, 0x5a, 0xed, 0xe1, 0x50, 0x01, 0x75, 0x4b, 0x3a, 0x6d, 0xd4, 0xea, - 0xe4, 0xad, 0xbc, 0xfd, 0xa0, 0x93, 0xb7, 0x1e, 0xd8, 0xab, 0x9d, 0xbc, 0xb5, 0x6a, 0xaf, 0x75, - 0xf2, 0xd6, 0x9a, 0x6d, 0x75, 0xf2, 0xd6, 0x96, 0x5d, 0xe8, 0xe4, 0xad, 0x82, 0x6d, 0x77, 0xf2, - 0x96, 0x6d, 0x17, 0x9f, 0x9e, 0xbe, 0xbf, 0xae, 0xe6, 0x3e, 0x5c, 0x57, 0x73, 0xff, 0x5e, 0x57, - 0x73, 0x7f, 0xde, 0x54, 0x57, 0x3e, 0xdc, 0x54, 0x57, 0xfe, 0xbe, 0xa9, 0xae, 0xbc, 0x3c, 0x4a, - 0xbd, 0xbc, 0x73, 0x5d, 0xd9, 0xe1, 0x29, 0x0e, 0x64, 0x6b, 0x74, 0x0f, 0x7b, 0xf3, 0xcd, 0x77, - 0xad, 0xe1, 0xf4, 0x36, 0xa6, 0x5f, 0x66, 0xb0, 0xaa, 0x6f, 0x56, 0x4f, 0xfe, 0x0b, 0x00, 0x00, - 0xff, 0xff, 0xbd, 0xdc, 0x6f, 0x4c, 0xdf, 0x09, 0x00, 0x00, + // 951 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x96, 0x41, 0x6f, 0xdb, 0xb6, + 0x17, 0xc0, 0xe3, 0xd6, 0x4d, 0x14, 0xa6, 0x89, 0x65, 0xd9, 0xf1, 0x5f, 0x4e, 0x1b, 0xdb, 0x71, + 0xfb, 0x1f, 0xbc, 0x43, 0x6c, 0x2c, 0x3d, 0x0c, 0x1b, 0x76, 0x58, 0xda, 0x0c, 0xa8, 0x8d, 0xa0, + 0x2b, 0x94, 0x62, 0x18, 0xba, 0x03, 0x41, 0x89, 0x8c, 0xcd, 0x45, 0x22, 0x3d, 0x92, 0x6e, 0x9c, + 0x7d, 0x88, 0x61, 0x1f, 0xa6, 0x1f, 0xa2, 0xc7, 0xa2, 0xa7, 0x62, 0x87, 0x62, 0x48, 0xbe, 0xc8, + 0x20, 0x4a, 0xb2, 0x65, 0x2b, 0x83, 0xd0, 0xc1, 0x27, 0x4b, 0x7c, 0x8f, 0xbf, 0x9f, 0x9f, 0xf5, + 0x44, 0x3f, 0xd0, 0x94, 0x4a, 0x50, 0x4c, 0x7a, 0x52, 0xa1, 0x0b, 0x42, 0x5d, 0xaf, 0x37, 0xe2, + 0x52, 0xc1, 0xdf, 0x39, 0x23, 0xdd, 0xb1, 0xe0, 0x8a, 0x5b, 0xa5, 0x28, 0xa1, 0x9b, 0x24, 0xec, + 0x65, 0x76, 0xbc, 0x41, 0x3e, 0xc5, 0x48, 0x71, 0x11, 0xed, 0xd8, 0xab, 0x0e, 0xf9, 0x90, 0xeb, + 0xcb, 0x5e, 0x78, 0x15, 0xaf, 0xd6, 0x3d, 0x2e, 0x03, 0x2e, 0x61, 0x14, 0x88, 0x6e, 0xa2, 0x50, + 0xfb, 0x63, 0x01, 0x54, 0x9e, 0xf1, 0x20, 0x98, 0x30, 0xaa, 0xae, 0x5e, 0x72, 0xee, 0x3b, 0xc4, + 0x45, 0x8a, 0x58, 0x3f, 0x82, 0x2d, 0xa1, 0xaf, 0xa0, 0x40, 0x8a, 0xd8, 0x85, 0x56, 0xa1, 0xb3, + 0xf9, 0xb4, 0xfb, 0xee, 0x53, 0x73, 0xed, 0xaf, 0x4f, 0xcd, 0x2f, 0x86, 0x54, 0x8d, 0x26, 0x6e, + 0xd7, 0xe3, 0x41, 0x4c, 0x8b, 0x3f, 0x0e, 0x25, 0xbe, 0xe8, 0xa9, 0xab, 0x31, 0x91, 0xdd, 0x13, + 0xe2, 0x39, 0x20, 0x42, 0x38, 0x21, 0x70, 0x0c, 0xf6, 0x7d, 0xfa, 0xdb, 0x84, 0x62, 0xa8, 0xbf, + 0x7c, 0xf8, 0x01, 0x15, 0xbf, 0x20, 0x0c, 0xa2, 0x80, 0x4f, 0x98, 0xb2, 0xef, 0x7c, 0xb6, 0xa2, + 0xcf, 0x94, 0x53, 0x8f, 0xa0, 0x67, 0x9a, 0x79, 0xa6, 0x5e, 0x85, 0xc4, 0x63, 0x0d, 0x6c, 0xff, + 0x51, 0x06, 0xc6, 0x73, 0x2e, 0xd5, 0x6b, 0xce, 0x88, 0x55, 0x07, 0x86, 0x37, 0x42, 0x94, 0x41, + 0x8a, 0xa3, 0x62, 0x9c, 0x0d, 0x7d, 0xdf, 0xc7, 0x56, 0x1b, 0xdc, 0x77, 0x89, 0x37, 0x7a, 0x72, + 0x34, 0x16, 0xe4, 0x9c, 0x4e, 0xed, 0xb2, 0x0e, 0x2f, 0xac, 0x59, 0x8f, 0xc0, 0xb6, 0xc7, 0x19, + 0x23, 0x9e, 0xa2, 0x5c, 0x33, 0xee, 0x44, 0x49, 0xf3, 0xc5, 0x3e, 0xb6, 0xba, 0xa0, 0xa2, 0x04, + 0x62, 0xf2, 0x9c, 0x08, 0xe8, 0x8d, 0x10, 0x63, 0xc4, 0x0f, 0x53, 0xef, 0xeb, 0xd4, 0x72, 0x12, + 0x7a, 0x16, 0x45, 0xfa, 0xd8, 0x7a, 0x00, 0x36, 0xa9, 0xeb, 0x41, 0x4c, 0x18, 0x0f, 0x6c, 0x43, + 0x67, 0x19, 0xd4, 0xf5, 0x4e, 0xc2, 0x7b, 0x6b, 0x1f, 0x00, 0xdd, 0x0e, 0x51, 0x74, 0x53, 0x47, + 0x37, 0xc3, 0x95, 0x28, 0xfc, 0x25, 0x30, 0x27, 0xcc, 0xe5, 0x0c, 0x53, 0x36, 0x84, 0x63, 0x22, + 0x28, 0xc7, 0xf6, 0x5e, 0xab, 0xd0, 0x29, 0x3a, 0xa5, 0xd9, 0xfa, 0x4b, 0xbd, 0x6c, 0x7d, 0x0b, + 0xc0, 0xac, 0x4d, 0xa4, 0x7d, 0xb7, 0x75, 0xb7, 0xb3, 0x75, 0xb4, 0xd7, 0x5d, 0x6a, 0xad, 0xee, + 0x4f, 0x49, 0x8a, 0x93, 0xca, 0xb6, 0x8e, 0x41, 0x09, 0x93, 0x31, 0x97, 0x54, 0x41, 0x84, 0xb1, + 0x20, 0x52, 0xda, 0x96, 0x7e, 0x4e, 0xf6, 0x87, 0xb7, 0x87, 0xd5, 0xb8, 0x93, 0x8e, 0xa3, 0xc8, + 0x99, 0x12, 0x94, 0x0d, 0x9d, 0x9d, 0x78, 0x43, 0xbc, 0x6a, 0xbd, 0x00, 0xb5, 0x4b, 0xaa, 0x46, + 0x58, 0xa0, 0x4b, 0xe4, 0x43, 0xea, 0xa1, 0x19, 0xa9, 0x96, 0x43, 0xaa, 0xce, 0xf7, 0xf5, 0x3d, + 0x94, 0xf0, 0xbe, 0x07, 0xa5, 0x73, 0x42, 0x16, 0x40, 0xff, 0xcb, 0x01, 0x6d, 0x9f, 0x13, 0x92, + 0x22, 0xbc, 0x00, 0x35, 0x4c, 0x7c, 0x32, 0x44, 0xd1, 0xc3, 0x4c, 0x81, 0xec, 0xbc, 0x6f, 0x34, + 0xdf, 0xb7, 0xc8, 0x13, 0x04, 0x93, 0x60, 0x9c, 0xe1, 0xd5, 0xf3, 0x78, 0xf3, 0x7d, 0x29, 0x1e, + 0x06, 0x6d, 0x2f, 0x79, 0x25, 0xe1, 0x98, 0x73, 0x1f, 0x26, 0xcf, 0x20, 0xcd, 0x6e, 0xe4, 0xb0, + 0x1b, 0x5e, 0xfa, 0xb5, 0x3e, 0x89, 0x08, 0x29, 0x8b, 0x0b, 0x0e, 0x96, 0x2c, 0x82, 0xa8, 0x89, + 0x58, 0x2c, 0xa0, 0x99, 0x23, 0xd9, 0xf7, 0x16, 0xcf, 0x8e, 0x10, 0x90, 0x72, 0x8c, 0xc0, 0xe3, + 0x25, 0x87, 0xee, 0x37, 0x38, 0xe2, 0xbe, 0x6e, 0xdc, 0x44, 0xd3, 0xca, 0xd1, 0xb4, 0x16, 0x34, + 0xfa, 0x65, 0x7f, 0x1e, 0x21, 0x12, 0xd3, 0xaf, 0xe0, 0xff, 0x99, 0x6a, 0x30, 0x21, 0x41, 0x46, + 0x75, 0x90, 0xa3, 0x3a, 0x58, 0xaa, 0x28, 0x84, 0x2c, 0xb9, 0x20, 0x68, 0x2e, 0xb9, 0x94, 0x20, + 0x48, 0x4e, 0xc4, 0xd5, 0xcc, 0xf2, 0x28, 0xc7, 0xf2, 0x70, 0xc1, 0xf2, 0x2a, 0xde, 0x9e, 0x08, + 0x7e, 0x01, 0x65, 0xc5, 0x15, 0x0a, 0x9f, 0x7b, 0xd2, 0x6e, 0xd2, 0xde, 0xfe, 0x4f, 0xe7, 0xa3, + 0xa9, 0x41, 0x27, 0x73, 0x8e, 0xc5, 0x40, 0xd5, 0x47, 0x52, 0xc1, 0x54, 0xcb, 0xea, 0x23, 0x1e, + 0x68, 0xfe, 0x77, 0x9f, 0x77, 0xc4, 0x7f, 0x78, 0x7b, 0x08, 0xe2, 0x02, 0xc3, 0x03, 0xdf, 0x0a, + 0xc9, 0xce, 0x0c, 0xac, 0x0f, 0x7e, 0x02, 0x4a, 0xcb, 0xaa, 0xad, 0x15, 0xa8, 0x76, 0xc4, 0xa2, + 0xc6, 0x07, 0x95, 0x80, 0xb2, 0x4c, 0x55, 0xd5, 0x15, 0xa8, 0xca, 0x01, 0x65, 0x4e, 0xd6, 0x86, + 0xa6, 0x19, 0xdb, 0xee, 0x4a, 0x6c, 0x68, 0xba, 0x64, 0xbb, 0x04, 0xf5, 0xb0, 0x36, 0xca, 0x18, + 0x11, 0x19, 0xe7, 0xc3, 0x15, 0x38, 0x6b, 0x01, 0x65, 0xfd, 0x90, 0x7e, 0x8b, 0x18, 0x4d, 0xff, + 0x45, 0xbc, 0xbf, 0x12, 0x31, 0x9a, 0xde, 0x26, 0xfe, 0x19, 0xec, 0x66, 0x5e, 0xe7, 0x70, 0x94, + 0xb0, 0xdb, 0xad, 0x42, 0x67, 0xeb, 0xe8, 0x71, 0xe6, 0xef, 0xeb, 0x96, 0x19, 0xc6, 0xa9, 0x78, + 0xb7, 0x0c, 0x36, 0x5f, 0x03, 0xdb, 0x97, 0x01, 0x4c, 0xcf, 0x22, 0x90, 0x30, 0xe4, 0xfa, 0x04, + 0xdb, 0x0f, 0x5a, 0x85, 0x8e, 0xe1, 0xec, 0xfa, 0x32, 0x38, 0x9d, 0x4f, 0x15, 0x3f, 0x44, 0x41, + 0xab, 0x06, 0xd6, 0x47, 0xc8, 0x57, 0x04, 0xdb, 0x15, 0x9d, 0x16, 0xdf, 0x0d, 0x8a, 0x46, 0xd1, + 0xbc, 0x37, 0x28, 0x1a, 0xf7, 0xcc, 0xf5, 0x41, 0xd1, 0x58, 0x37, 0x37, 0x06, 0x45, 0x63, 0xc3, + 0x34, 0x06, 0x45, 0x63, 0xc7, 0x2c, 0x0d, 0x8a, 0x46, 0xc9, 0x34, 0x07, 0x45, 0xc3, 0x34, 0xcb, + 0x4f, 0x4f, 0xdf, 0x5d, 0x37, 0x0a, 0xef, 0xaf, 0x1b, 0x85, 0xbf, 0xaf, 0x1b, 0x85, 0x3f, 0x6f, + 0x1a, 0x6b, 0xef, 0x6f, 0x1a, 0x6b, 0x1f, 0x6f, 0x1a, 0x6b, 0xaf, 0x8f, 0x52, 0x3f, 0xde, 0x99, + 0xae, 0xec, 0xf0, 0x14, 0xb9, 0xb2, 0x17, 0x8f, 0x7b, 0x6f, 0xbe, 0xfa, 0xa6, 0x37, 0x9d, 0x0f, + 0x7d, 0xfa, 0xc7, 0x74, 0xd7, 0xf5, 0x00, 0xf7, 0xe4, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb3, + 0xfb, 0xde, 0xab, 0x46, 0x0a, 0x00, 0x00, } func (m *CommunityPoolRebate) Marshal() (dAtA []byte, err error) { @@ -360,9 +413,9 @@ func (m *CommunityPoolRebate) MarshalToSizedBuffer(dAtA []byte) (int, error) { var l int _ = l { - size := m.LiquidStakeAmount.Size() + size := m.LiquidStakedStTokenAmount.Size() i -= size - if _, err := m.LiquidStakeAmount.MarshalTo(dAtA[i:]); err != nil { + if _, err := m.LiquidStakedStTokenAmount.MarshalTo(dAtA[i:]); err != nil { return 0, err } i = encodeVarintHostZone(dAtA, i, uint64(size)) @@ -370,9 +423,9 @@ func (m *CommunityPoolRebate) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 { - size := m.RebatePercentage.Size() + size := m.RebateRate.Size() i -= size - if _, err := m.RebatePercentage.MarshalTo(dAtA[i:]); err != nil { + if _, err := m.RebateRate.MarshalTo(dAtA[i:]); err != nil { return 0, err } i = encodeVarintHostZone(dAtA, i, uint64(size)) @@ -402,6 +455,15 @@ func (m *HostZone) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.CommunityPoolTreasuryAddress) > 0 { + i -= len(m.CommunityPoolTreasuryAddress) + copy(dAtA[i:], m.CommunityPoolTreasuryAddress) + i = encodeVarintHostZone(dAtA, i, uint64(len(m.CommunityPoolTreasuryAddress))) + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0x9a + } if m.CommunityPoolRebate != nil { { size, err := m.CommunityPoolRebate.MarshalToSizedBuffer(dAtA[:i]) @@ -684,9 +746,9 @@ func (m *CommunityPoolRebate) Size() (n int) { } var l int _ = l - l = m.RebatePercentage.Size() + l = m.RebateRate.Size() n += 1 + l + sovHostZone(uint64(l)) - l = m.LiquidStakeAmount.Size() + l = m.LiquidStakedStTokenAmount.Size() n += 1 + l + sovHostZone(uint64(l)) return n } @@ -790,6 +852,10 @@ func (m *HostZone) Size() (n int) { l = m.CommunityPoolRebate.Size() n += 2 + l + sovHostZone(uint64(l)) } + l = len(m.CommunityPoolTreasuryAddress) + if l > 0 { + n += 2 + l + sovHostZone(uint64(l)) + } return n } @@ -830,7 +896,7 @@ func (m *CommunityPoolRebate) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RebatePercentage", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RebateRate", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -858,13 +924,13 @@ func (m *CommunityPoolRebate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.RebatePercentage.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.RebateRate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LiquidStakeAmount", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field LiquidStakedStTokenAmount", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -892,7 +958,7 @@ func (m *CommunityPoolRebate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.LiquidStakeAmount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.LiquidStakedStTokenAmount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1793,6 +1859,38 @@ func (m *HostZone) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 35: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CommunityPoolTreasuryAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHostZone + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthHostZone + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthHostZone + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CommunityPoolTreasuryAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipHostZone(dAtA[iNdEx:]) diff --git a/x/stakeibc/types/host_zone_test.go b/x/stakeibc/types/host_zone_test.go index aa0debc504..dbffe84207 100644 --- a/x/stakeibc/types/host_zone_test.go +++ b/x/stakeibc/types/host_zone_test.go @@ -79,7 +79,7 @@ func TestSafelyGetCommunityPoolRebate(t *testing.T) { hostZone: types.HostZone{ ChainId: chainId, CommunityPoolRebate: &types.CommunityPoolRebate{ - LiquidStakeAmount: sdkmath.NewInt(1), + LiquidStakedStTokenAmount: sdkmath.NewInt(1), }, }, expectedRebate: false, @@ -89,7 +89,7 @@ func TestSafelyGetCommunityPoolRebate(t *testing.T) { hostZone: types.HostZone{ ChainId: chainId, CommunityPoolRebate: &types.CommunityPoolRebate{ - RebatePercentage: sdk.OneDec(), + RebateRate: sdk.OneDec(), }, }, expectedRebate: false, @@ -99,8 +99,8 @@ func TestSafelyGetCommunityPoolRebate(t *testing.T) { hostZone: types.HostZone{ ChainId: chainId, CommunityPoolRebate: &types.CommunityPoolRebate{ - RebatePercentage: sdk.OneDec(), - LiquidStakeAmount: sdkmath.NewInt(1), + RebateRate: sdk.OneDec(), + LiquidStakedStTokenAmount: sdkmath.NewInt(1), }, }, expectedRebate: true, diff --git a/x/stakeibc/types/message_register_host_zone.go b/x/stakeibc/types/message_register_host_zone.go index d66b039f2f..07e4ef5649 100644 --- a/x/stakeibc/types/message_register_host_zone.go +++ b/x/stakeibc/types/message_register_host_zone.go @@ -27,18 +27,20 @@ func NewMsgRegisterHostZone( minRedemptionRate sdk.Dec, maxRedemptionRate sdk.Dec, lsmLiquidStakeEnabled bool, + communityPoolTreasuryAddress string, ) *MsgRegisterHostZone { return &MsgRegisterHostZone{ - Creator: creator, - ConnectionId: connectionId, - Bech32Prefix: bech32prefix, - HostDenom: hostDenom, - IbcDenom: ibcDenom, - TransferChannelId: transferChannelId, - UnbondingPeriod: unbondingPeriod, - MinRedemptionRate: minRedemptionRate, - MaxRedemptionRate: maxRedemptionRate, - LsmLiquidStakeEnabled: lsmLiquidStakeEnabled, + Creator: creator, + ConnectionId: connectionId, + Bech32Prefix: bech32prefix, + HostDenom: hostDenom, + IbcDenom: ibcDenom, + TransferChannelId: transferChannelId, + UnbondingPeriod: unbondingPeriod, + MinRedemptionRate: minRedemptionRate, + MaxRedemptionRate: maxRedemptionRate, + LsmLiquidStakeEnabled: lsmLiquidStakeEnabled, + CommunityPoolTreasuryAddress: communityPoolTreasuryAddress, } } diff --git a/x/stakeibc/types/message_set_community_pool_rebate.go b/x/stakeibc/types/message_set_community_pool_rebate.go index e41b12ca5f..fce4d5af62 100644 --- a/x/stakeibc/types/message_set_community_pool_rebate.go +++ b/x/stakeibc/types/message_set_community_pool_rebate.go @@ -12,7 +12,7 @@ import ( "github.com/Stride-Labs/stride/v19/utils" ) -const TypeMsgSetCommunityPoolRebate = "register_community_pool_rebate" +const TypeMsgSetCommunityPoolRebate = "set_community_pool_rebate" var _ sdk.Msg = &MsgSetCommunityPoolRebate{} @@ -20,13 +20,13 @@ func NewMsgSetCommunityPoolRebate( creator string, chainId string, rebateRate sdk.Dec, - liquidStakedAmount sdkmath.Int, + liquidStakedStTokenAmount sdkmath.Int, ) *MsgSetCommunityPoolRebate { return &MsgSetCommunityPoolRebate{ - Creator: creator, - ChainId: chainId, - RebateRate: rebateRate, - LiquidStakedAmount: liquidStakedAmount, + Creator: creator, + ChainId: chainId, + RebateRate: rebateRate, + LiquidStakedStTokenAmount: liquidStakedStTokenAmount, } } @@ -65,7 +65,7 @@ func (msg *MsgSetCommunityPoolRebate) ValidateBasic() error { if msg.RebateRate.IsNil() || msg.RebateRate.LT(sdk.ZeroDec()) || msg.RebateRate.GT(sdk.OneDec()) { return errors.New("invalid rebate rate, must be a decimal between 0 and 1 (inclusive)") } - if msg.LiquidStakedAmount.IsNil() || msg.LiquidStakedAmount.LT(sdkmath.ZeroInt()) { + if msg.LiquidStakedStTokenAmount.IsNil() || msg.LiquidStakedStTokenAmount.LT(sdkmath.ZeroInt()) { return errors.New("invalid liquid stake amount, must be greater than or equal to zero") } diff --git a/x/stakeibc/types/message_set_community_pool_rebate_test.go b/x/stakeibc/types/message_set_community_pool_rebate_test.go index 62998e4606..117de1e25a 100644 --- a/x/stakeibc/types/message_set_community_pool_rebate_test.go +++ b/x/stakeibc/types/message_set_community_pool_rebate_test.go @@ -31,87 +31,87 @@ func TestMsgSetCommunityPoolRebate(t *testing.T) { { name: "valid message", msg: types.MsgSetCommunityPoolRebate{ - Creator: validAdminAddress, - ChainId: validChainId, - RebateRate: validRebateRate, - LiquidStakedAmount: validLiquidStakedAmount, + Creator: validAdminAddress, + ChainId: validChainId, + RebateRate: validRebateRate, + LiquidStakedStTokenAmount: validLiquidStakedAmount, }, }, { name: "invalid address", msg: types.MsgSetCommunityPoolRebate{ - Creator: invalidAddress, - ChainId: validChainId, - RebateRate: validRebateRate, - LiquidStakedAmount: validLiquidStakedAmount, + Creator: invalidAddress, + ChainId: validChainId, + RebateRate: validRebateRate, + LiquidStakedStTokenAmount: validLiquidStakedAmount, }, err: "invalid creator address", }, { name: "not admin address", msg: types.MsgSetCommunityPoolRebate{ - Creator: validNotAdminAddress, - ChainId: validChainId, - RebateRate: validRebateRate, - LiquidStakedAmount: validLiquidStakedAmount, + Creator: validNotAdminAddress, + ChainId: validChainId, + RebateRate: validRebateRate, + LiquidStakedStTokenAmount: validLiquidStakedAmount, }, err: "not an admin", }, { name: "invalid chain ID", msg: types.MsgSetCommunityPoolRebate{ - Creator: validAdminAddress, - ChainId: "", - RebateRate: validRebateRate, - LiquidStakedAmount: validLiquidStakedAmount, + Creator: validAdminAddress, + ChainId: "", + RebateRate: validRebateRate, + LiquidStakedStTokenAmount: validLiquidStakedAmount, }, err: "chain ID must be specified", }, { name: "invalid rebate rate - nil", msg: types.MsgSetCommunityPoolRebate{ - Creator: validAdminAddress, - ChainId: validChainId, - LiquidStakedAmount: validLiquidStakedAmount, + Creator: validAdminAddress, + ChainId: validChainId, + LiquidStakedStTokenAmount: validLiquidStakedAmount, }, err: "rebate rate, must be a decimal between 0 and 1 (inclusive)", }, { name: "invalid rebate rate - less than 0", msg: types.MsgSetCommunityPoolRebate{ - Creator: validAdminAddress, - ChainId: validChainId, - RebateRate: sdk.MustNewDecFromStr("0.5").Neg(), - LiquidStakedAmount: validLiquidStakedAmount, + Creator: validAdminAddress, + ChainId: validChainId, + RebateRate: sdk.MustNewDecFromStr("0.5").Neg(), + LiquidStakedStTokenAmount: validLiquidStakedAmount, }, err: "rebate rate, must be a decimal between 0 and 1 (inclusive)", }, { name: "valid rebate rate - one", msg: types.MsgSetCommunityPoolRebate{ - Creator: validAdminAddress, - ChainId: validChainId, - RebateRate: sdk.OneDec(), - LiquidStakedAmount: validLiquidStakedAmount, + Creator: validAdminAddress, + ChainId: validChainId, + RebateRate: sdk.OneDec(), + LiquidStakedStTokenAmount: validLiquidStakedAmount, }, }, { name: "invalid rebate rate - greater than one", msg: types.MsgSetCommunityPoolRebate{ - Creator: validAdminAddress, - ChainId: validChainId, - RebateRate: sdk.MustNewDecFromStr("1.1"), - LiquidStakedAmount: validLiquidStakedAmount, + Creator: validAdminAddress, + ChainId: validChainId, + RebateRate: sdk.MustNewDecFromStr("1.1"), + LiquidStakedStTokenAmount: validLiquidStakedAmount, }, err: "rebate rate, must be a decimal between 0 and 1 (inclusive)", }, { name: "valid zero rebate", msg: types.MsgSetCommunityPoolRebate{ - Creator: validAdminAddress, - ChainId: validChainId, - RebateRate: sdk.ZeroDec(), - LiquidStakedAmount: validLiquidStakedAmount, + Creator: validAdminAddress, + ChainId: validChainId, + RebateRate: sdk.ZeroDec(), + LiquidStakedStTokenAmount: validLiquidStakedAmount, }, }, { @@ -126,20 +126,20 @@ func TestMsgSetCommunityPoolRebate(t *testing.T) { { name: "invalid liquid stake amount - less than 0", msg: types.MsgSetCommunityPoolRebate{ - Creator: validAdminAddress, - ChainId: validChainId, - RebateRate: validRebateRate, - LiquidStakedAmount: sdkmath.NewInt(1).Neg(), + Creator: validAdminAddress, + ChainId: validChainId, + RebateRate: validRebateRate, + LiquidStakedStTokenAmount: sdkmath.NewInt(1).Neg(), }, err: "invalid liquid stake amount, must be greater than or equal to zero", }, { name: "valid liquid stake amount - zero", msg: types.MsgSetCommunityPoolRebate{ - Creator: validAdminAddress, - ChainId: validChainId, - RebateRate: validRebateRate, - LiquidStakedAmount: sdkmath.ZeroInt(), + Creator: validAdminAddress, + ChainId: validChainId, + RebateRate: validRebateRate, + LiquidStakedStTokenAmount: sdkmath.ZeroInt(), }, }, } @@ -149,7 +149,7 @@ func TestMsgSetCommunityPoolRebate(t *testing.T) { if test.err == "" { require.NoError(t, test.msg.ValidateBasic(), "test: %v", test.name) require.Equal(t, test.msg.Route(), types.RouterKey) - require.Equal(t, test.msg.Type(), "register_community_pool_rebate") + require.Equal(t, test.msg.Type(), "set_community_pool_rebate") signers := test.msg.GetSigners() require.Equal(t, len(signers), 1) diff --git a/x/stakeibc/types/tx.pb.go b/x/stakeibc/types/tx.pb.go index 13c0d4f8dc..14efb3099b 100644 --- a/x/stakeibc/types/tx.pb.go +++ b/x/stakeibc/types/tx.pb.go @@ -544,16 +544,17 @@ var xxx_messageInfo_MsgRedeemStakeResponse proto.InternalMessageInfo // next: 15 type MsgRegisterHostZone struct { - ConnectionId string `protobuf:"bytes,2,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" yaml:"connection_id"` - Bech32Prefix string `protobuf:"bytes,12,opt,name=bech32prefix,proto3" json:"bech32prefix,omitempty"` - HostDenom string `protobuf:"bytes,4,opt,name=host_denom,json=hostDenom,proto3" json:"host_denom,omitempty" yaml:"host_denom"` - IbcDenom string `protobuf:"bytes,5,opt,name=ibc_denom,json=ibcDenom,proto3" json:"ibc_denom,omitempty" yaml:"ibc_denom"` - Creator string `protobuf:"bytes,6,opt,name=creator,proto3" json:"creator,omitempty"` - TransferChannelId string `protobuf:"bytes,10,opt,name=transfer_channel_id,json=transferChannelId,proto3" json:"transfer_channel_id,omitempty" yaml:"transfer_channel_id"` - UnbondingPeriod uint64 `protobuf:"varint,11,opt,name=unbonding_period,json=unbondingPeriod,proto3" json:"unbonding_period,omitempty" yaml:"unbonding_period"` - MinRedemptionRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,13,opt,name=min_redemption_rate,json=minRedemptionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"min_redemption_rate"` - MaxRedemptionRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,14,opt,name=max_redemption_rate,json=maxRedemptionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"max_redemption_rate"` - LsmLiquidStakeEnabled bool `protobuf:"varint,15,opt,name=lsm_liquid_stake_enabled,json=lsmLiquidStakeEnabled,proto3" json:"lsm_liquid_stake_enabled,omitempty"` + ConnectionId string `protobuf:"bytes,2,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" yaml:"connection_id"` + Bech32Prefix string `protobuf:"bytes,12,opt,name=bech32prefix,proto3" json:"bech32prefix,omitempty"` + HostDenom string `protobuf:"bytes,4,opt,name=host_denom,json=hostDenom,proto3" json:"host_denom,omitempty" yaml:"host_denom"` + IbcDenom string `protobuf:"bytes,5,opt,name=ibc_denom,json=ibcDenom,proto3" json:"ibc_denom,omitempty" yaml:"ibc_denom"` + Creator string `protobuf:"bytes,6,opt,name=creator,proto3" json:"creator,omitempty"` + TransferChannelId string `protobuf:"bytes,10,opt,name=transfer_channel_id,json=transferChannelId,proto3" json:"transfer_channel_id,omitempty" yaml:"transfer_channel_id"` + UnbondingPeriod uint64 `protobuf:"varint,11,opt,name=unbonding_period,json=unbondingPeriod,proto3" json:"unbonding_period,omitempty" yaml:"unbonding_period"` + MinRedemptionRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,13,opt,name=min_redemption_rate,json=minRedemptionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"min_redemption_rate"` + MaxRedemptionRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,14,opt,name=max_redemption_rate,json=maxRedemptionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"max_redemption_rate"` + LsmLiquidStakeEnabled bool `protobuf:"varint,15,opt,name=lsm_liquid_stake_enabled,json=lsmLiquidStakeEnabled,proto3" json:"lsm_liquid_stake_enabled,omitempty"` + CommunityPoolTreasuryAddress string `protobuf:"bytes,16,opt,name=community_pool_treasury_address,json=communityPoolTreasuryAddress,proto3" json:"community_pool_treasury_address,omitempty"` } func (m *MsgRegisterHostZone) Reset() { *m = MsgRegisterHostZone{} } @@ -1997,8 +1998,8 @@ type MsgSetCommunityPoolRebate struct { ChainId string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` // Rebate percentage represented as a decimal (e.g. 0.2 for 20%) RebateRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=rebate_rate,json=rebateRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"rebate_rate"` - // Number of native tokens staked by the community pool - LiquidStakedAmount github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,4,opt,name=liquid_staked_amount,json=liquidStakedAmount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"liquid_staked_amount"` + // Number of stTokens recieved by the community pool after liquid staking + LiquidStakedStTokenAmount github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,4,opt,name=liquid_staked_st_token_amount,json=liquidStakedStTokenAmount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"liquid_staked_st_token_amount"` } func (m *MsgSetCommunityPoolRebate) Reset() { *m = MsgSetCommunityPoolRebate{} } @@ -2241,151 +2242,154 @@ func init() { func init() { proto.RegisterFile("stride/stakeibc/tx.proto", fileDescriptor_9b7e09c9ad51cd54) } var fileDescriptor_9b7e09c9ad51cd54 = []byte{ - // 2300 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0x5f, 0x6f, 0x1b, 0xc7, - 0x11, 0x17, 0xad, 0x7f, 0xd4, 0x48, 0xb2, 0xa8, 0x93, 0x64, 0x53, 0xe7, 0x98, 0x94, 0x4f, 0x4e, - 0xaa, 0xca, 0x31, 0x59, 0xc9, 0x41, 0xdb, 0x28, 0x29, 0x50, 0x49, 0x76, 0x13, 0x35, 0x96, 0x6d, - 0x9c, 0x14, 0x1b, 0x30, 0x10, 0x5c, 0x96, 0x77, 0x6b, 0xf2, 0xe0, 0xbb, 0x5b, 0xe6, 0xee, 0x28, - 0xd1, 0x79, 0x28, 0x82, 0x02, 0x05, 0x8a, 0xa2, 0x45, 0x5b, 0x14, 0x7d, 0xeb, 0x43, 0x0a, 0x14, - 0x68, 0xd1, 0xbe, 0x04, 0x45, 0x3e, 0x44, 0x8a, 0x02, 0x45, 0x90, 0xa7, 0xa2, 0x05, 0xd4, 0xc2, - 0x7e, 0x48, 0x9f, 0xfd, 0x09, 0x8a, 0xdd, 0xbd, 0x5b, 0xde, 0x1d, 0x97, 0xa4, 0xa4, 0xa8, 0x46, - 0x5f, 0x44, 0xee, 0xee, 0xec, 0xcc, 0x6f, 0x66, 0x67, 0x67, 0x67, 0x86, 0x82, 0x62, 0x10, 0xfa, - 0xb6, 0x85, 0xab, 0x41, 0x88, 0x1e, 0x63, 0xbb, 0x66, 0x56, 0xc3, 0x76, 0xa5, 0xe9, 0x93, 0x90, - 0x28, 0x33, 0x7c, 0xa5, 0x12, 0xaf, 0xa8, 0xe5, 0x2c, 0xe9, 0x01, 0x72, 0x6c, 0x0b, 0x85, 0xc4, - 0xe7, 0x3b, 0xd4, 0xf9, 0x3a, 0xa9, 0x13, 0xf6, 0xb5, 0x4a, 0xbf, 0x45, 0xb3, 0x8b, 0x26, 0x09, - 0x5c, 0x12, 0x18, 0x7c, 0x81, 0x0f, 0xa2, 0xa5, 0x12, 0x1f, 0x55, 0x6b, 0x28, 0xc0, 0xd5, 0x83, - 0xb5, 0x1a, 0x0e, 0xd1, 0x5a, 0xd5, 0x24, 0xb6, 0x17, 0xad, 0x5f, 0x8c, 0xd6, 0xdd, 0xa0, 0x5e, - 0x3d, 0x58, 0xa3, 0x1f, 0xd1, 0xc2, 0x2c, 0x72, 0x6d, 0x8f, 0x54, 0xd9, 0x5f, 0x3e, 0xa5, 0xfd, - 0xf5, 0x1c, 0x68, 0xbb, 0x41, 0xfd, 0xdd, 0xa6, 0x85, 0x42, 0xbc, 0xe3, 0x79, 0xd8, 0xd7, 0xb1, - 0x85, 0xdd, 0x66, 0x68, 0x13, 0x4f, 0x47, 0x21, 0xde, 0x22, 0x2d, 0xcf, 0x0a, 0x94, 0x22, 0x8c, - 0x9b, 0x3e, 0xa6, 0xa0, 0x8b, 0xb9, 0xa5, 0xdc, 0xca, 0x84, 0x1e, 0x0f, 0x95, 0x45, 0xc8, 0x9b, - 0x0d, 0x64, 0x7b, 0x86, 0x6d, 0x15, 0xcf, 0x45, 0x4b, 0x74, 0xbc, 0x63, 0x29, 0x87, 0xb0, 0xe8, - 0xd2, 0x05, 0xca, 0xd5, 0xf0, 0x05, 0x5b, 0xc3, 0x47, 0x21, 0x2e, 0x0e, 0x53, 0xda, 0xad, 0x37, - 0x3f, 0x3b, 0x2a, 0x0f, 0xfd, 0xe3, 0xa8, 0xfc, 0x4a, 0xdd, 0x0e, 0x1b, 0xad, 0x5a, 0xc5, 0x24, - 0x6e, 0xa4, 0x6b, 0xf4, 0x71, 0x3d, 0xb0, 0x1e, 0x57, 0xc3, 0x27, 0x4d, 0x1c, 0x54, 0x6e, 0x62, - 0xf3, 0x8b, 0x4f, 0xaf, 0x43, 0x64, 0x8a, 0x9b, 0xd8, 0xd4, 0x2f, 0xb8, 0xb6, 0x27, 0xc1, 0xcc, - 0x04, 0xa3, 0x76, 0x0f, 0xc1, 0x23, 0x67, 0x22, 0x18, 0xb5, 0x25, 0x82, 0xb5, 0x57, 0x61, 0x75, - 0xb0, 0x31, 0x75, 0x1c, 0x34, 0x89, 0x17, 0x60, 0xed, 0x97, 0x39, 0x38, 0xbf, 0x1b, 0xd4, 0x6f, - 0xdb, 0x1f, 0xb4, 0x6c, 0x6b, 0x8f, 0xba, 0x47, 0x1f, 0x3b, 0x7f, 0x0f, 0xc6, 0x90, 0x4b, 0x5a, - 0x5e, 0xc8, 0xad, 0xbc, 0x55, 0x39, 0x81, 0x02, 0x3b, 0x5e, 0xa8, 0x47, 0xbb, 0x95, 0xcb, 0x00, - 0x0d, 0x12, 0x84, 0x86, 0x85, 0x3d, 0xe2, 0xf2, 0x53, 0xd0, 0x27, 0xe8, 0xcc, 0x4d, 0x3a, 0xa1, - 0x7d, 0x94, 0x83, 0x0b, 0x69, 0x4c, 0x31, 0x5c, 0xe5, 0x11, 0xe4, 0x83, 0xd0, 0x08, 0xc9, 0x63, - 0xec, 0x31, 0x70, 0x93, 0xeb, 0x8b, 0x95, 0xc8, 0x26, 0xd4, 0x13, 0x2b, 0x91, 0x27, 0x56, 0xb6, - 0x89, 0xed, 0x6d, 0x7d, 0x83, 0xc2, 0xfb, 0xe3, 0xbf, 0xca, 0x2b, 0xc7, 0x80, 0x47, 0x37, 0x04, - 0xfa, 0x78, 0x10, 0xee, 0x53, 0xde, 0xda, 0xef, 0x72, 0x30, 0x4b, 0x21, 0xec, 0xed, 0xbe, 0x58, - 0xcb, 0x5c, 0x87, 0x39, 0x27, 0x70, 0xb9, 0x82, 0x86, 0x5d, 0x33, 0x53, 0x26, 0x2a, 0x38, 0x81, - 0xcb, 0xe0, 0xed, 0xd4, 0x4c, 0x6e, 0xa9, 0x3b, 0xb0, 0xd8, 0x85, 0x52, 0xd8, 0x6a, 0x0d, 0xe6, - 0x43, 0x1f, 0x79, 0x01, 0x32, 0x99, 0xe3, 0x99, 0xc4, 0x6d, 0x3a, 0x38, 0xc4, 0x0c, 0x7a, 0x5e, - 0x9f, 0x4b, 0xac, 0x6d, 0x47, 0x4b, 0xda, 0x1f, 0x72, 0x30, 0xb3, 0x1b, 0xd4, 0xb7, 0x1d, 0x8c, - 0xfc, 0x2d, 0xe4, 0x20, 0xcf, 0xc4, 0xa7, 0xbb, 0x76, 0x1d, 0x7b, 0x0c, 0x7f, 0x25, 0x7b, 0x50, - 0xe1, 0x0d, 0xe4, 0x79, 0xd8, 0xe1, 0x77, 0x46, 0x8f, 0x87, 0xda, 0x22, 0x5c, 0xcc, 0x20, 0x15, - 0x3e, 0xfd, 0x27, 0xee, 0xd3, 0xd4, 0xef, 0xb1, 0xfb, 0xa2, 0x4e, 0xee, 0x12, 0x30, 0x0f, 0x36, - 0x3e, 0x24, 0x5e, 0x14, 0x58, 0xf4, 0x3c, 0x9d, 0x78, 0x48, 0x3c, 0xac, 0xa8, 0x90, 0xf7, 0xb1, - 0x89, 0xed, 0x03, 0xec, 0x47, 0x7a, 0x88, 0xb1, 0x56, 0x64, 0xce, 0x9e, 0x00, 0x2b, 0xf4, 0xf8, - 0xf3, 0x28, 0xcc, 0xb1, 0xa5, 0xba, 0x1d, 0x84, 0xd8, 0x7f, 0x3b, 0xe6, 0xf6, 0x1d, 0x98, 0x36, - 0x89, 0xe7, 0x61, 0x7e, 0xae, 0xb1, 0xf1, 0xb7, 0x8a, 0xcf, 0x8f, 0xca, 0xf3, 0x4f, 0x90, 0xeb, - 0x6c, 0x68, 0xa9, 0x65, 0x4d, 0x9f, 0xea, 0x8c, 0x77, 0x2c, 0x45, 0x83, 0xa9, 0x1a, 0x36, 0x1b, - 0x37, 0xd6, 0x9b, 0x3e, 0x7e, 0x64, 0xb7, 0x8b, 0x53, 0x0c, 0x50, 0x6a, 0x4e, 0x79, 0x2d, 0x75, - 0x43, 0x79, 0xb8, 0x5a, 0x78, 0x7e, 0x54, 0x9e, 0xe5, 0xfc, 0x3b, 0x6b, 0x5a, 0xe2, 0xe2, 0x2a, - 0x6b, 0x30, 0xd1, 0xf1, 0xd9, 0x51, 0xb6, 0x69, 0xfe, 0xf9, 0x51, 0xb9, 0xc0, 0x37, 0x89, 0x25, - 0x4d, 0xcf, 0xdb, 0x91, 0x07, 0x27, 0x0f, 0x66, 0x2c, 0x7d, 0x30, 0x77, 0x80, 0xbb, 0xe8, 0x23, - 0xec, 0x1b, 0xd1, 0xa1, 0x53, 0x5d, 0x81, 0xb1, 0x2d, 0x3d, 0x3f, 0x2a, 0xab, 0x9c, 0xad, 0x84, - 0x48, 0xd3, 0x67, 0xe3, 0xd9, 0x6d, 0x3e, 0xc9, 0x5c, 0xb2, 0xd0, 0xf2, 0x6a, 0xc4, 0xb3, 0x6c, - 0xaf, 0x6e, 0x34, 0xb1, 0x6f, 0x13, 0xab, 0x38, 0xb9, 0x94, 0x5b, 0x19, 0xd9, 0xba, 0xf4, 0xfc, - 0xa8, 0x7c, 0x91, 0x33, 0xcb, 0x52, 0x68, 0xfa, 0x8c, 0x98, 0xba, 0xc7, 0x66, 0x14, 0x07, 0xe6, - 0xe8, 0x8b, 0x92, 0x0d, 0xe9, 0xd3, 0x67, 0x10, 0xd2, 0x67, 0x5d, 0xdb, 0xcb, 0x3c, 0x23, 0x54, - 0x1a, 0x6a, 0x77, 0x49, 0x3b, 0x7f, 0x26, 0xd2, 0x50, 0x3b, 0x23, 0xed, 0x5b, 0x50, 0xa4, 0xe1, - 0xc7, 0x61, 0xd1, 0xc4, 0x60, 0xd9, 0x82, 0x81, 0x3d, 0x54, 0x73, 0xb0, 0x55, 0x9c, 0x61, 0x61, - 0x63, 0xc1, 0x09, 0xdc, 0x44, 0xb0, 0xb9, 0xc5, 0x17, 0x37, 0xf2, 0x3f, 0xfe, 0xb8, 0x3c, 0xf4, - 0x9f, 0x8f, 0xcb, 0x43, 0xda, 0x65, 0xb8, 0x24, 0xf1, 0x59, 0xe1, 0xd3, 0x3f, 0xcf, 0xb1, 0x90, - 0xb5, 0xed, 0x20, 0xdb, 0x7d, 0xd7, 0xb3, 0xb0, 0x83, 0xeb, 0x28, 0xc4, 0x16, 0x0b, 0x6b, 0xfd, - 0x9e, 0xf8, 0x25, 0x98, 0x12, 0xd7, 0xab, 0x13, 0x6f, 0x20, 0xbe, 0x61, 0x3b, 0x96, 0x32, 0x0f, - 0xa3, 0xb8, 0x49, 0xcc, 0x06, 0xbb, 0x7c, 0x23, 0x3a, 0x1f, 0xa4, 0x6e, 0xde, 0x68, 0xfa, 0xe6, - 0x7d, 0x7f, 0x24, 0x3f, 0x52, 0x18, 0xd5, 0x96, 0xe1, 0x4a, 0x4f, 0x40, 0x02, 0x76, 0x18, 0x5d, - 0xd2, 0x1a, 0x0f, 0x35, 0xf7, 0xe3, 0xf4, 0xa9, 0x1f, 0xe4, 0x54, 0x44, 0x38, 0x97, 0x89, 0x08, - 0xcb, 0x30, 0xed, 0xb5, 0x5c, 0xc3, 0x8f, 0x39, 0x46, 0xa8, 0xa7, 0xbc, 0x96, 0x2b, 0xa4, 0x68, - 0x4b, 0x50, 0x92, 0x4b, 0x15, 0xb8, 0x7e, 0x94, 0x83, 0xc2, 0x6e, 0x50, 0xdf, 0xb4, 0xac, 0xaf, - 0x0e, 0x69, 0x03, 0x40, 0xa4, 0x85, 0x41, 0x71, 0x78, 0x69, 0x78, 0x65, 0x72, 0x5d, 0xad, 0x64, - 0x52, 0xc9, 0x8a, 0x90, 0xa3, 0x27, 0xa8, 0x35, 0x15, 0x8a, 0x59, 0x18, 0x02, 0xe3, 0x7b, 0x30, - 0x23, 0x66, 0x1f, 0x60, 0xbb, 0xde, 0x08, 0x95, 0x75, 0x18, 0x47, 0x96, 0xe5, 0xe3, 0x20, 0xe0, - 0x08, 0xb7, 0x8a, 0x5f, 0x7c, 0x7a, 0x7d, 0x3e, 0xf2, 0xcd, 0x4d, 0xbe, 0xb2, 0x17, 0xfa, 0xb6, - 0x57, 0xd7, 0x63, 0x42, 0xe5, 0x02, 0x8c, 0x1d, 0xb2, 0xdd, 0x0c, 0xf8, 0x88, 0x1e, 0x8d, 0xb4, - 0xdf, 0x46, 0x1e, 0xd5, 0x40, 0x5e, 0x1d, 0x67, 0x04, 0x9d, 0xda, 0x16, 0xbb, 0x30, 0x2b, 0xb4, - 0x33, 0xb8, 0xa0, 0xd8, 0x24, 0x4b, 0xbd, 0x4d, 0xc2, 0x85, 0xea, 0x85, 0x83, 0x0c, 0x8a, 0xd8, - 0xc7, 0xa4, 0x10, 0x85, 0x9d, 0x3e, 0xca, 0x81, 0xb2, 0x1b, 0xd4, 0x6f, 0x62, 0xfa, 0x14, 0x0b, - 0xaa, 0xd3, 0x6a, 0x70, 0x03, 0xf2, 0x07, 0xc8, 0x31, 0xa8, 0xf5, 0xa2, 0x37, 0xb8, 0x8f, 0x8d, - 0x0f, 0x90, 0x43, 0x67, 0xb4, 0x97, 0x40, 0xed, 0x46, 0x20, 0x00, 0xfe, 0x26, 0x17, 0xdd, 0xed, - 0x20, 0x24, 0x3e, 0xde, 0xf1, 0x42, 0xec, 0xb3, 0xf7, 0x7e, 0xd3, 0x34, 0xc5, 0x63, 0x7d, 0xe2, - 0x4c, 0x61, 0x39, 0xfb, 0x98, 0xf1, 0xb7, 0x33, 0xfd, 0x64, 0x2d, 0xc3, 0x34, 0xe2, 0x42, 0x0c, - 0x72, 0xe8, 0x89, 0x47, 0x74, 0x2a, 0x9a, 0xbc, 0x4b, 0xe7, 0xb4, 0x97, 0x61, 0xb9, 0x0f, 0x3a, - 0xa1, 0xc5, 0x07, 0xb0, 0x24, 0xf2, 0x63, 0xa1, 0xe3, 0x5e, 0x03, 0xf9, 0x38, 0xb8, 0xd5, 0x36, - 0x1b, 0x2c, 0x0e, 0x9e, 0x4a, 0x93, 0x22, 0x50, 0x3b, 0x92, 0x26, 0x8e, 0x0c, 0xae, 0xc7, 0x43, - 0x6d, 0x15, 0x56, 0x06, 0x89, 0x14, 0xf0, 0xea, 0x2c, 0xd2, 0x6c, 0x23, 0xc7, 0xae, 0xd1, 0x48, - 0x7f, 0x93, 0x07, 0x24, 0x9b, 0x78, 0x67, 0x0d, 0x8a, 0x07, 0x17, 0x89, 0x20, 0x01, 0xe5, 0x6d, - 0x96, 0x03, 0xeb, 0x38, 0x68, 0xb9, 0x58, 0x24, 0x1f, 0xa7, 0x41, 0xa1, 0x5d, 0x62, 0x57, 0x34, - 0xcd, 0x49, 0x88, 0xf9, 0x69, 0x9e, 0xa5, 0x39, 0xdb, 0x94, 0x0d, 0xde, 0xf7, 0x91, 0x85, 0x75, - 0xd2, 0x0a, 0xb1, 0xf2, 0x4d, 0x98, 0x40, 0xad, 0xb0, 0x41, 0x7c, 0x3b, 0x7c, 0x32, 0x30, 0x4c, - 0x74, 0x48, 0x15, 0x0d, 0xa6, 0xd9, 0xb5, 0xc8, 0x80, 0x99, 0xa4, 0x93, 0xdb, 0x91, 0x59, 0xb6, - 0xa0, 0xc4, 0x6f, 0xb1, 0x11, 0x12, 0xc3, 0xc7, 0x87, 0xc8, 0xb7, 0x0c, 0x99, 0x1b, 0xaa, 0x9c, - 0x6a, 0x9f, 0xe8, 0x8c, 0x66, 0x3b, 0xe9, 0x94, 0xdf, 0x85, 0xcb, 0x1d, 0x1e, 0x21, 0xc5, 0x9d, - 0x61, 0xc1, 0x9d, 0x74, 0x31, 0x66, 0xc1, 0x54, 0x4b, 0x71, 0xd8, 0x01, 0x9e, 0x49, 0x75, 0x30, - 0xc8, 0x32, 0x1e, 0xfe, 0x6c, 0x5d, 0xa6, 0x94, 0x31, 0x8e, 0xfd, 0xae, 0xec, 0xe6, 0x1d, 0x58, - 0x8e, 0x59, 0xc4, 0x60, 0x64, 0xbc, 0x78, 0x8e, 0x55, 0xe2, 0xa4, 0x11, 0xa4, 0x6e, 0x66, 0x6f, - 0xc1, 0x95, 0x88, 0x05, 0x31, 0x38, 0x40, 0x09, 0xab, 0x71, 0xc6, 0xea, 0x25, 0x46, 0xb8, 0x4f, - 0xe8, 0xa9, 0x76, 0x33, 0xaa, 0xc2, 0x7c, 0x84, 0x8a, 0x25, 0x7e, 0x06, 0xf1, 0x18, 0xbf, 0x62, - 0x9e, 0xed, 0x9d, 0xe5, 0x6b, 0x2c, 0x11, 0xbc, 0xeb, 0x51, 0x0e, 0xca, 0x0d, 0xb8, 0x90, 0xdd, - 0xc0, 0xc7, 0xc5, 0x09, 0xb6, 0x65, 0x2e, 0xb5, 0x85, 0x1b, 0x43, 0x59, 0x83, 0x85, 0xec, 0x26, - 0x86, 0x8a, 0xe7, 0x8a, 0xba, 0x92, 0xda, 0xc3, 0x54, 0xa6, 0x75, 0x56, 0x27, 0x87, 0xed, 0x6c, - 0x98, 0xe4, 0x75, 0x96, 0xc8, 0x68, 0x63, 0xf2, 0x6b, 0xa0, 0xa4, 0xc9, 0x99, 0x16, 0x3c, 0x71, - 0x9e, 0x49, 0x50, 0x33, 0x1d, 0x2e, 0xc2, 0x78, 0x93, 0x10, 0x66, 0xa3, 0x69, 0xfe, 0x52, 0xd1, - 0xe1, 0x8e, 0xa5, 0x6c, 0x80, 0x4a, 0x73, 0x39, 0xe4, 0x38, 0xe4, 0x10, 0x5b, 0x46, 0x70, 0x88, - 0x9a, 0x86, 0x43, 0x82, 0x20, 0x91, 0xd2, 0xb1, 0xaa, 0x7e, 0x93, 0x13, 0xec, 0x1d, 0xa2, 0xe6, - 0x6d, 0x12, 0x04, 0x2c, 0x22, 0xdd, 0x87, 0x19, 0x9a, 0x75, 0xb2, 0x3d, 0x51, 0xbd, 0x32, 0x73, - 0xaa, 0x7a, 0x65, 0xda, 0xb5, 0x3d, 0xca, 0x79, 0x93, 0x97, 0x2d, 0x94, 0x2f, 0x6a, 0xa7, 0xf8, - 0x16, 0x4e, 0xc9, 0x17, 0xb5, 0x3b, 0x7c, 0x37, 0xbe, 0xfd, 0xc3, 0x2f, 0x3f, 0x59, 0xed, 0x5c, - 0xca, 0x9f, 0x7c, 0xf9, 0xc9, 0xea, 0xcb, 0x51, 0x13, 0xaa, 0xdd, 0x69, 0x43, 0x49, 0xae, 0x7d, - 0x94, 0x40, 0x66, 0xa7, 0x45, 0xb4, 0xf8, 0x4b, 0x8e, 0x45, 0x0b, 0xfe, 0x46, 0x9d, 0x41, 0xb4, - 0xb8, 0x02, 0x53, 0x49, 0xe7, 0x89, 0x83, 0x45, 0xc2, 0x67, 0x06, 0xb4, 0x2b, 0x8e, 0xaf, 0x6a, - 0x16, 0x73, 0xa4, 0x6a, 0x76, 0x5a, 0xa8, 0xfa, 0xb7, 0x61, 0xa6, 0x2a, 0x7f, 0x37, 0xfe, 0x1f, - 0x54, 0x4d, 0xba, 0xf6, 0xc8, 0x09, 0x5c, 0x7b, 0xf4, 0xa4, 0xae, 0x3d, 0xf6, 0x3f, 0x72, 0xed, - 0xf1, 0x17, 0xea, 0xda, 0xd9, 0x83, 0x8b, 0xce, 0x3b, 0x3b, 0x2d, 0xce, 0xfb, 0x9f, 0xe7, 0xd8, - 0x33, 0xb9, 0x87, 0xc3, 0x6d, 0xe2, 0xba, 0x2d, 0xcf, 0x0e, 0x9f, 0xdc, 0x23, 0xc4, 0xa1, 0xf9, - 0x7f, 0x88, 0x69, 0xce, 0x9c, 0x7a, 0x78, 0xfb, 0xe5, 0x73, 0xc7, 0x48, 0x0c, 0xee, 0xc2, 0xa4, - 0xcf, 0x18, 0x27, 0x5b, 0xa1, 0x95, 0x93, 0x15, 0x94, 0x3a, 0x70, 0x16, 0xec, 0x18, 0xdf, 0x87, - 0xf9, 0x64, 0xdd, 0x68, 0xc5, 0x36, 0x1f, 0x39, 0x95, 0xcd, 0x15, 0xa7, 0x53, 0x64, 0x5a, 0x91, - 0xe1, 0xdf, 0xa4, 0x86, 0x8f, 0x75, 0xa3, 0x66, 0xbf, 0x26, 0x35, 0xbb, 0xdc, 0x7e, 0x51, 0x0e, - 0x2e, 0x5f, 0x14, 0x47, 0xf0, 0xeb, 0x73, 0xac, 0x90, 0xd9, 0x27, 0xf5, 0xba, 0x83, 0xe3, 0x07, - 0x3b, 0xf4, 0x89, 0xe3, 0x60, 0xff, 0xac, 0x4f, 0x60, 0x0f, 0x66, 0x9b, 0xd8, 0x77, 0xed, 0x20, - 0x60, 0xed, 0x39, 0x56, 0x1c, 0xb0, 0x73, 0x38, 0xbf, 0xfe, 0x4a, 0x57, 0x8d, 0xb1, 0xd9, 0x0a, - 0x1b, 0x1f, 0xde, 0x13, 0xe4, 0xbc, 0x94, 0xd0, 0x0b, 0xcd, 0xcc, 0x0c, 0x4d, 0xcf, 0xe2, 0xca, - 0x2a, 0x6a, 0x98, 0x45, 0xc3, 0x8d, 0x37, 0xb2, 0xd6, 0x5b, 0x95, 0x5a, 0x4f, 0xaa, 0xba, 0xa6, - 0xb1, 0xa4, 0x59, 0xba, 0x16, 0xdb, 0x6e, 0xb5, 0x02, 0x0b, 0x52, 0x94, 0xca, 0x04, 0x8c, 0xbe, - 0xa5, 0x6f, 0xde, 0xd9, 0x2f, 0x0c, 0x29, 0x00, 0x63, 0xfa, 0xad, 0xfb, 0x77, 0xdf, 0xb9, 0x55, - 0xc8, 0xad, 0xff, 0x7e, 0x16, 0x86, 0x77, 0x83, 0xba, 0xf2, 0x00, 0x26, 0x93, 0x4d, 0xd6, 0x72, - 0x97, 0xee, 0xe9, 0x5e, 0xb0, 0xfa, 0xb5, 0x01, 0x04, 0xa2, 0x01, 0xfa, 0x3e, 0x9c, 0xcf, 0x34, - 0x70, 0x35, 0xe9, 0xd6, 0x14, 0x8d, 0xba, 0x3a, 0x98, 0x46, 0x48, 0x78, 0x00, 0x93, 0xc9, 0x2e, - 0xa3, 0x14, 0x7a, 0x82, 0x40, 0x0e, 0x5d, 0xd2, 0xfa, 0x53, 0x1e, 0x41, 0xa1, 0xab, 0xed, 0x77, - 0x55, 0xbe, 0x39, 0x4d, 0xa5, 0xbe, 0x7a, 0x1c, 0x2a, 0x21, 0xa7, 0x0d, 0x17, 0x7a, 0xb4, 0x62, - 0xa4, 0x66, 0x90, 0xd3, 0xaa, 0xeb, 0xc7, 0xa7, 0x15, 0x92, 0x09, 0xcc, 0xc9, 0xda, 0x29, 0x3d, - 0x2c, 0xd4, 0x45, 0xa8, 0x56, 0x8f, 0x49, 0x28, 0x04, 0xbe, 0x07, 0xd3, 0xe9, 0x36, 0xc9, 0x15, - 0x19, 0x87, 0x14, 0x89, 0xfa, 0xf5, 0x81, 0x24, 0x82, 0xfd, 0x21, 0x2c, 0x48, 0xeb, 0xfb, 0x1e, - 0x86, 0x94, 0xb6, 0x02, 0x7a, 0x18, 0xb2, 0x6f, 0xdb, 0x40, 0x31, 0x61, 0x26, 0xdb, 0x32, 0x58, - 0x96, 0xb1, 0xc9, 0x10, 0xa9, 0xd7, 0x8e, 0x41, 0x24, 0x84, 0xfc, 0x00, 0x8a, 0x3d, 0xcb, 0xfe, - 0x1e, 0x1e, 0x27, 0xa7, 0x56, 0x5f, 0x3b, 0x09, 0xb5, 0x90, 0xff, 0xb3, 0x1c, 0x5c, 0xee, 0x5f, - 0xb2, 0xaf, 0xc9, 0xf8, 0xf6, 0xdd, 0xa2, 0xbe, 0x7e, 0xe2, 0x2d, 0x49, 0xef, 0x95, 0x95, 0xe8, - 0x52, 0xef, 0x95, 0x10, 0xca, 0xbd, 0xb7, 0x4f, 0x2d, 0xae, 0x3c, 0x84, 0xa9, 0xd4, 0xaf, 0x32, - 0x4b, 0xf2, 0x2b, 0xd7, 0xa1, 0x50, 0x57, 0x06, 0x51, 0x08, 0xde, 0xbf, 0xca, 0x41, 0x79, 0xd0, - 0x8f, 0xaf, 0x37, 0x7a, 0xdb, 0xaa, 0xe7, 0x26, 0xf5, 0x8d, 0x53, 0x6c, 0x4a, 0x46, 0xef, 0x4c, - 0xeb, 0x41, 0xeb, 0xe1, 0x3a, 0x09, 0x1a, 0x79, 0xf4, 0x96, 0x37, 0x1e, 0x68, 0x90, 0xed, 0x6a, - 0x3a, 0x48, 0x83, 0x6c, 0x96, 0x4a, 0x1e, 0x64, 0x7b, 0x95, 0x2c, 0x54, 0x4e, 0x57, 0xb9, 0x72, - 0xb5, 0xf7, 0xed, 0x1b, 0x24, 0xa7, 0x57, 0xbd, 0x40, 0xe5, 0x74, 0xd5, 0x0a, 0x57, 0x7b, 0x1f, - 0xc1, 0x20, 0x39, 0xbd, 0xf2, 0x54, 0xfa, 0x68, 0xf4, 0xc8, 0x51, 0xa5, 0xd6, 0x97, 0xd3, 0xca, - 0x63, 0x5d, 0xff, 0xf4, 0x4c, 0x69, 0xc1, 0x82, 0x3c, 0x35, 0x93, 0x06, 0x6a, 0x29, 0xa9, 0xba, - 0x76, 0x6c, 0xd2, 0x58, 0xec, 0xd6, 0xed, 0xcf, 0x9e, 0x96, 0x72, 0x9f, 0x3f, 0x2d, 0xe5, 0xfe, - 0xfd, 0xb4, 0x94, 0xfb, 0xc5, 0xb3, 0xd2, 0xd0, 0xe7, 0xcf, 0x4a, 0x43, 0x7f, 0x7f, 0x56, 0x1a, - 0x7a, 0xb8, 0x9e, 0x48, 0x67, 0xf7, 0x18, 0xdb, 0xeb, 0xb7, 0x51, 0x2d, 0xa8, 0x46, 0xa9, 0xd5, - 0xc1, 0xda, 0xeb, 0xc9, 0xf4, 0x8a, 0xa5, 0xb7, 0xb5, 0x31, 0xf6, 0x5f, 0x0f, 0x37, 0xfe, 0x1b, - 0x00, 0x00, 0xff, 0xff, 0x77, 0xf5, 0x3e, 0xb4, 0xc0, 0x21, 0x00, 0x00, + // 2342 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcf, 0x6f, 0xdc, 0xc6, + 0xf5, 0xd7, 0x5a, 0xbf, 0x56, 0x4f, 0x92, 0xb5, 0xa2, 0x24, 0x7b, 0x45, 0x47, 0xbb, 0x32, 0x95, + 0xe4, 0xab, 0xaf, 0x1c, 0xef, 0x56, 0x72, 0xd0, 0x36, 0x4a, 0x0a, 0x54, 0x92, 0xdd, 0x44, 0x8d, + 0x65, 0x1b, 0x94, 0x62, 0x03, 0x06, 0x02, 0x96, 0x4b, 0x8e, 0x77, 0x09, 0x93, 0x9c, 0x0d, 0xc9, + 0x95, 0xd6, 0x39, 0x14, 0x41, 0x81, 0x02, 0x45, 0xd1, 0xa2, 0x2d, 0x8a, 0xde, 0x7a, 0x48, 0x81, + 0x02, 0x2d, 0xda, 0x4b, 0x0e, 0xf9, 0x23, 0x52, 0x14, 0x28, 0x82, 0x9c, 0x8a, 0x1e, 0xd4, 0xc2, + 0x3e, 0xa4, 0x40, 0x6f, 0xbe, 0xf5, 0x56, 0xcc, 0x0f, 0xce, 0x92, 0xdc, 0xd9, 0x5d, 0x49, 0x51, + 0x8d, 0x5e, 0x2c, 0x71, 0xe6, 0x33, 0xef, 0x7d, 0xde, 0x9b, 0x37, 0x6f, 0xde, 0x3c, 0x19, 0x8a, + 0x61, 0x14, 0x38, 0x36, 0xaa, 0x86, 0x91, 0xf9, 0x18, 0x39, 0x35, 0xab, 0x1a, 0xb5, 0x2b, 0xcd, + 0x00, 0x47, 0x58, 0x99, 0x61, 0x33, 0x95, 0x78, 0x46, 0x2d, 0x67, 0xa1, 0x87, 0xa6, 0xeb, 0xd8, + 0x66, 0x84, 0x03, 0xb6, 0x42, 0x9d, 0xaf, 0xe3, 0x3a, 0xa6, 0xbf, 0x56, 0xc9, 0x6f, 0x7c, 0x74, + 0xd1, 0xc2, 0xa1, 0x87, 0x43, 0x83, 0x4d, 0xb0, 0x0f, 0x3e, 0x55, 0x62, 0x5f, 0xd5, 0x9a, 0x19, + 0xa2, 0xea, 0xe1, 0x7a, 0x0d, 0x45, 0xe6, 0x7a, 0xd5, 0xc2, 0x8e, 0xcf, 0xe7, 0x2f, 0xf3, 0x79, + 0x2f, 0xac, 0x57, 0x0f, 0xd7, 0xc9, 0x0f, 0x3e, 0x31, 0x6b, 0x7a, 0x8e, 0x8f, 0xab, 0xf4, 0x5f, + 0x36, 0xa4, 0xfd, 0xf9, 0x02, 0x68, 0x7b, 0x61, 0xfd, 0xbd, 0xa6, 0x6d, 0x46, 0x68, 0xd7, 0xf7, + 0x51, 0xa0, 0x23, 0x1b, 0x79, 0xcd, 0xc8, 0xc1, 0xbe, 0x6e, 0x46, 0x68, 0x1b, 0xb7, 0x7c, 0x3b, + 0x54, 0x8a, 0x30, 0x6e, 0x05, 0x88, 0x90, 0x2e, 0xe6, 0x96, 0x73, 0xab, 0x13, 0x7a, 0xfc, 0xa9, + 0x2c, 0x42, 0xde, 0x6a, 0x98, 0x8e, 0x6f, 0x38, 0x76, 0xf1, 0x02, 0x9f, 0x22, 0xdf, 0xbb, 0xb6, + 0x72, 0x04, 0x8b, 0x1e, 0x99, 0x20, 0x52, 0x8d, 0x40, 0x88, 0x35, 0x02, 0x33, 0x42, 0xc5, 0x61, + 0x82, 0xdd, 0x7e, 0xeb, 0xb3, 0xe3, 0xf2, 0xd0, 0xdf, 0x8e, 0xcb, 0xaf, 0xd6, 0x9d, 0xa8, 0xd1, + 0xaa, 0x55, 0x2c, 0xec, 0x71, 0x5b, 0xf9, 0x8f, 0xeb, 0xa1, 0xfd, 0xb8, 0x1a, 0x3d, 0x69, 0xa2, + 0xb0, 0x72, 0x13, 0x59, 0x5f, 0x7c, 0x7a, 0x1d, 0xb8, 0x2b, 0x6e, 0x22, 0x4b, 0xbf, 0xe4, 0x39, + 0xbe, 0x84, 0x33, 0x55, 0x6c, 0xb6, 0x7b, 0x28, 0x1e, 0x39, 0x17, 0xc5, 0x66, 0x5b, 0xa2, 0x58, + 0x7b, 0x0d, 0xd6, 0x06, 0x3b, 0x53, 0x47, 0x61, 0x13, 0xfb, 0x21, 0xd2, 0x7e, 0x91, 0x83, 0x8b, + 0x7b, 0x61, 0xfd, 0xb6, 0xf3, 0x41, 0xcb, 0xb1, 0xf7, 0x49, 0x78, 0xf4, 0xf1, 0xf3, 0x77, 0x60, + 0xcc, 0xf4, 0x70, 0xcb, 0x8f, 0x98, 0x97, 0xb7, 0x2b, 0xa7, 0x30, 0x60, 0xd7, 0x8f, 0x74, 0xbe, + 0x5a, 0x59, 0x02, 0x68, 0xe0, 0x30, 0x32, 0x6c, 0xe4, 0x63, 0x8f, 0xed, 0x82, 0x3e, 0x41, 0x46, + 0x6e, 0x92, 0x01, 0xed, 0xa3, 0x1c, 0x5c, 0x4a, 0x73, 0x8a, 0xe9, 0x2a, 0x8f, 0x20, 0x1f, 0x46, + 0x46, 0x84, 0x1f, 0x23, 0x9f, 0x92, 0x9b, 0xdc, 0x58, 0xac, 0x70, 0x9f, 0x90, 0x48, 0xac, 0xf0, + 0x48, 0xac, 0xec, 0x60, 0xc7, 0xdf, 0xfe, 0x1a, 0xa1, 0xf7, 0x87, 0xbf, 0x97, 0x57, 0x4f, 0x40, + 0x8f, 0x2c, 0x08, 0xf5, 0xf1, 0x30, 0x3a, 0x20, 0xb2, 0xb5, 0xdf, 0xe6, 0x60, 0x96, 0x50, 0xd8, + 0xdf, 0x7b, 0xb1, 0x9e, 0xb9, 0x0e, 0x73, 0x6e, 0xe8, 0x31, 0x03, 0x0d, 0xa7, 0x66, 0xa5, 0x5c, + 0x54, 0x70, 0x43, 0x8f, 0xd2, 0xdb, 0xad, 0x59, 0xcc, 0x53, 0x77, 0x60, 0xb1, 0x8b, 0xa5, 0xf0, + 0xd5, 0x3a, 0xcc, 0x47, 0x81, 0xe9, 0x87, 0xa6, 0x45, 0x03, 0xcf, 0xc2, 0x5e, 0xd3, 0x45, 0x11, + 0xa2, 0xd4, 0xf3, 0xfa, 0x5c, 0x62, 0x6e, 0x87, 0x4f, 0x69, 0xbf, 0xcf, 0xc1, 0xcc, 0x5e, 0x58, + 0xdf, 0x71, 0x91, 0x19, 0x6c, 0x9b, 0xae, 0xe9, 0x5b, 0xe8, 0x6c, 0xc7, 0xae, 0xe3, 0x8f, 0xe1, + 0xaf, 0xe4, 0x0f, 0xa2, 0xbc, 0x61, 0xfa, 0x3e, 0x72, 0xd9, 0x99, 0xd1, 0xe3, 0x4f, 0x6d, 0x11, + 0x2e, 0x67, 0x98, 0x8a, 0x98, 0xfe, 0x23, 0x8b, 0x69, 0x12, 0xf7, 0xc8, 0x7b, 0x51, 0x3b, 0x77, + 0x05, 0x68, 0x04, 0x1b, 0x1f, 0x62, 0x9f, 0x27, 0x16, 0x3d, 0x4f, 0x06, 0x1e, 0x62, 0x1f, 0x29, + 0x2a, 0xe4, 0x03, 0x64, 0x21, 0xe7, 0x10, 0x05, 0xdc, 0x0e, 0xf1, 0xad, 0x15, 0x69, 0xb0, 0x27, + 0xc8, 0x0a, 0x3b, 0xfe, 0x3d, 0x0a, 0x73, 0x74, 0xaa, 0xee, 0x84, 0x11, 0x0a, 0xde, 0x89, 0xa5, + 0x7d, 0x0b, 0xa6, 0x2d, 0xec, 0xfb, 0x88, 0xed, 0x6b, 0xec, 0xfc, 0xed, 0xe2, 0xf3, 0xe3, 0xf2, + 0xfc, 0x13, 0xd3, 0x73, 0x37, 0xb5, 0xd4, 0xb4, 0xa6, 0x4f, 0x75, 0xbe, 0x77, 0x6d, 0x45, 0x83, + 0xa9, 0x1a, 0xb2, 0x1a, 0x37, 0x36, 0x9a, 0x01, 0x7a, 0xe4, 0xb4, 0x8b, 0x53, 0x94, 0x50, 0x6a, + 0x4c, 0x79, 0x3d, 0x75, 0x42, 0x59, 0xba, 0x5a, 0x78, 0x7e, 0x5c, 0x9e, 0x65, 0xf2, 0x3b, 0x73, + 0x5a, 0xe2, 0xe0, 0x2a, 0xeb, 0x30, 0xd1, 0x89, 0xd9, 0x51, 0xba, 0x68, 0xfe, 0xf9, 0x71, 0xb9, + 0xc0, 0x16, 0x89, 0x29, 0x4d, 0xcf, 0x3b, 0x3c, 0x82, 0x93, 0x1b, 0x33, 0x96, 0xde, 0x98, 0x3b, + 0xc0, 0x42, 0xf4, 0x11, 0x0a, 0x0c, 0xbe, 0xe9, 0xc4, 0x56, 0xa0, 0x62, 0x4b, 0xcf, 0x8f, 0xcb, + 0x2a, 0x13, 0x2b, 0x01, 0x69, 0xfa, 0x6c, 0x3c, 0xba, 0xc3, 0x06, 0x69, 0x48, 0x16, 0x5a, 0x7e, + 0x0d, 0xfb, 0xb6, 0xe3, 0xd7, 0x8d, 0x26, 0x0a, 0x1c, 0x6c, 0x17, 0x27, 0x97, 0x73, 0xab, 0x23, + 0xdb, 0x57, 0x9e, 0x1f, 0x97, 0x2f, 0x33, 0x61, 0x59, 0x84, 0xa6, 0xcf, 0x88, 0xa1, 0x7b, 0x74, + 0x44, 0x71, 0x61, 0x8e, 0xdc, 0x28, 0xd9, 0x94, 0x3e, 0x7d, 0x0e, 0x29, 0x7d, 0xd6, 0x73, 0xfc, + 0xcc, 0x35, 0x42, 0xb4, 0x99, 0xed, 0x2e, 0x6d, 0x17, 0xcf, 0x45, 0x9b, 0xd9, 0xce, 0x68, 0xfb, + 0x06, 0x14, 0x49, 0xfa, 0x71, 0x69, 0x36, 0x31, 0x68, 0xb5, 0x60, 0x20, 0xdf, 0xac, 0xb9, 0xc8, + 0x2e, 0xce, 0xd0, 0xb4, 0xb1, 0xe0, 0x86, 0x5e, 0x22, 0xd9, 0xdc, 0x62, 0x93, 0xca, 0x2d, 0x28, + 0x5b, 0xd8, 0xf3, 0x5a, 0xbe, 0x13, 0x3d, 0x31, 0x9a, 0x18, 0xbb, 0x46, 0x14, 0x20, 0x33, 0x6c, + 0x05, 0x4f, 0x0c, 0xd3, 0xb6, 0x03, 0x14, 0x86, 0xc5, 0x02, 0xdd, 0xde, 0x97, 0x04, 0xec, 0x1e, + 0xc6, 0xee, 0x01, 0x07, 0x6d, 0x31, 0xcc, 0x66, 0xfe, 0x47, 0x1f, 0x97, 0x87, 0xfe, 0xf9, 0x71, + 0x79, 0x48, 0x5b, 0x82, 0x2b, 0x92, 0xd0, 0x17, 0x47, 0xe3, 0x67, 0x39, 0x9a, 0xf9, 0x76, 0x5c, + 0xd3, 0xf1, 0xde, 0xf3, 0x6d, 0xe4, 0xa2, 0xba, 0x19, 0x21, 0x9b, 0x66, 0xc7, 0x7e, 0x95, 0xc2, + 0x32, 0x4c, 0x89, 0x53, 0xda, 0x49, 0x5b, 0x10, 0x1f, 0xd4, 0x5d, 0x5b, 0x99, 0x87, 0x51, 0xd4, + 0xc4, 0x56, 0x83, 0x9e, 0xe1, 0x11, 0x9d, 0x7d, 0xa4, 0x0e, 0xf0, 0x68, 0xfa, 0x00, 0x7f, 0x77, + 0x24, 0x3f, 0x52, 0x18, 0xd5, 0x56, 0xe0, 0x6a, 0x4f, 0x42, 0x82, 0x76, 0xc4, 0xcf, 0x7a, 0x8d, + 0x65, 0xac, 0xfb, 0x71, 0x15, 0xd6, 0x8f, 0x72, 0x2a, 0xb1, 0x5c, 0xc8, 0x24, 0x96, 0x15, 0x98, + 0xf6, 0x5b, 0x9e, 0x11, 0xc4, 0x12, 0x39, 0xeb, 0x29, 0xbf, 0xe5, 0x09, 0x2d, 0xda, 0x32, 0x94, + 0xe4, 0x5a, 0x05, 0xaf, 0x1f, 0xe6, 0xa0, 0xb0, 0x17, 0xd6, 0xb7, 0x6c, 0xfb, 0xab, 0x53, 0xda, + 0x04, 0x10, 0xd5, 0x65, 0x58, 0x1c, 0x5e, 0x1e, 0x5e, 0x9d, 0xdc, 0x50, 0x2b, 0x99, 0x8a, 0xb4, + 0x22, 0xf4, 0xe8, 0x09, 0xb4, 0xa6, 0x42, 0x31, 0x4b, 0x43, 0x70, 0x7c, 0x1f, 0x66, 0xc4, 0xe8, + 0x03, 0xe4, 0xd4, 0x1b, 0x91, 0xb2, 0x01, 0xe3, 0x71, 0x74, 0xe5, 0x58, 0x0a, 0xfc, 0xe2, 0xd3, + 0xeb, 0xf3, 0x3c, 0xc4, 0x79, 0x4c, 0xed, 0x47, 0x81, 0xe3, 0xd7, 0xf5, 0x18, 0xa8, 0x5c, 0x82, + 0xb1, 0x23, 0xba, 0x9a, 0x12, 0x1f, 0xd1, 0xf9, 0x97, 0xf6, 0x1b, 0x1e, 0x51, 0x0d, 0xd3, 0xaf, + 0xa3, 0x8c, 0xa2, 0x33, 0xfb, 0x62, 0x0f, 0x66, 0x85, 0x75, 0x06, 0x53, 0x14, 0xbb, 0x64, 0xb9, + 0xb7, 0x4b, 0x98, 0x52, 0xbd, 0x70, 0x98, 0x61, 0x11, 0xc7, 0x98, 0x94, 0xa2, 0xf0, 0xd3, 0x47, + 0x39, 0x50, 0xf6, 0xc2, 0xfa, 0x4d, 0x44, 0x6e, 0x74, 0x81, 0x3a, 0xab, 0x05, 0x37, 0x20, 0x7f, + 0x68, 0xba, 0xf4, 0x10, 0xf3, 0xab, 0xbc, 0x8f, 0x8f, 0x0f, 0x4d, 0x97, 0x8c, 0x68, 0x2f, 0x81, + 0xda, 0xcd, 0x40, 0x10, 0xfc, 0x75, 0x8e, 0x9f, 0xed, 0x30, 0xc2, 0x01, 0xda, 0xf5, 0x23, 0x14, + 0xd0, 0xb2, 0x61, 0xcb, 0xb2, 0xc4, 0x9d, 0x7f, 0xea, 0x82, 0x63, 0x25, 0x7b, 0x27, 0xb2, 0x2b, + 0x38, 0x7d, 0xf3, 0xad, 0xc0, 0xb4, 0xc9, 0x94, 0x18, 0xf8, 0xc8, 0x17, 0x77, 0xf1, 0x14, 0x1f, + 0xbc, 0x4b, 0xc6, 0xb4, 0x57, 0x60, 0xa5, 0x0f, 0x3b, 0x61, 0xc5, 0x07, 0xb0, 0x2c, 0xca, 0x6c, + 0x61, 0xe3, 0x7e, 0xc3, 0x0c, 0x50, 0x78, 0xab, 0x6d, 0x35, 0x68, 0x3a, 0x3d, 0x93, 0x25, 0x45, + 0x20, 0x7e, 0xc4, 0x4d, 0xc4, 0x1d, 0xae, 0xc7, 0x9f, 0xda, 0x1a, 0xac, 0x0e, 0x52, 0x29, 0xe8, + 0xd5, 0x69, 0xa6, 0xd9, 0x31, 0x5d, 0xa7, 0x46, 0x2e, 0x8c, 0x9b, 0x2c, 0x21, 0x39, 0xd8, 0x3f, + 0x6f, 0x52, 0x2c, 0xb9, 0x48, 0x14, 0x09, 0x2a, 0xef, 0xd0, 0x52, 0x5a, 0x47, 0x61, 0xcb, 0x43, + 0xa2, 0x86, 0x39, 0x0b, 0x0b, 0xed, 0x0a, 0x3d, 0xa2, 0x69, 0x49, 0x42, 0xcd, 0x4f, 0xf2, 0xb4, + 0x5a, 0xda, 0x21, 0x62, 0xd0, 0x41, 0x60, 0xda, 0x48, 0xc7, 0xad, 0x08, 0x29, 0x5f, 0x87, 0x09, + 0xb3, 0x15, 0x35, 0x70, 0xe0, 0x44, 0x4f, 0x06, 0xa6, 0x89, 0x0e, 0x54, 0xd1, 0x60, 0x9a, 0x1e, + 0x8b, 0x0c, 0x99, 0x49, 0x32, 0xb8, 0xc3, 0xdd, 0xb2, 0x0d, 0x25, 0x76, 0x8a, 0x8d, 0x08, 0x1b, + 0x01, 0x3a, 0x32, 0x03, 0xdb, 0x90, 0x85, 0xa1, 0xca, 0x50, 0x07, 0x58, 0xa7, 0x98, 0x9d, 0x64, + 0x50, 0x7e, 0x1b, 0x96, 0x3a, 0x32, 0x22, 0xc2, 0x3b, 0x23, 0x82, 0x05, 0xe9, 0x62, 0x2c, 0x82, + 0x9a, 0x96, 0x92, 0xb0, 0x0b, 0xac, 0x20, 0xeb, 0x70, 0x90, 0x15, 0x4e, 0xec, 0xda, 0x5a, 0x22, + 0xc8, 0x98, 0xc7, 0x41, 0x57, 0x91, 0xf4, 0x2e, 0xac, 0xc4, 0x22, 0x62, 0x32, 0x32, 0x59, 0xac, + 0x54, 0x2b, 0x31, 0x28, 0xa7, 0xd4, 0x2d, 0xec, 0x6d, 0xb8, 0xca, 0x45, 0x60, 0x83, 0x11, 0x94, + 0x88, 0x1a, 0x67, 0x65, 0x01, 0x05, 0x1e, 0x60, 0xb2, 0xab, 0xdd, 0x82, 0xaa, 0x30, 0xcf, 0x59, + 0xd1, 0xfa, 0xd1, 0xc0, 0x3e, 0x95, 0x57, 0xcc, 0xd3, 0xb5, 0xb3, 0x6c, 0x8e, 0xd6, 0x93, 0x77, + 0x7d, 0x22, 0x41, 0xb9, 0x01, 0x97, 0xb2, 0x0b, 0xd8, 0x77, 0x71, 0x82, 0x2e, 0x99, 0x4b, 0x2d, + 0x61, 0xce, 0x50, 0xd6, 0x61, 0x21, 0xbb, 0x88, 0xb2, 0x62, 0x25, 0xa7, 0xae, 0xa4, 0xd6, 0x50, + 0x93, 0xc9, 0x73, 0xad, 0x53, 0x0a, 0x77, 0x16, 0x4c, 0xb2, 0xe7, 0x9a, 0x28, 0x8c, 0x63, 0xf8, + 0x35, 0x50, 0xd2, 0x70, 0x6a, 0x05, 0xab, 0xbf, 0x67, 0x12, 0x68, 0x6a, 0xc3, 0x65, 0x18, 0xa7, + 0x85, 0x94, 0x63, 0xd3, 0xda, 0x72, 0x44, 0x1f, 0x23, 0x9f, 0xbb, 0xb6, 0xb2, 0x09, 0x2a, 0x29, + 0x09, 0x4d, 0xd7, 0xc5, 0x47, 0xc8, 0x36, 0xc2, 0x23, 0xb3, 0x69, 0xb8, 0x38, 0x0c, 0x13, 0x95, + 0x21, 0x6d, 0x0e, 0x6c, 0x31, 0xc0, 0xfe, 0x91, 0xd9, 0xbc, 0x8d, 0xc3, 0x90, 0x66, 0xa4, 0xfb, + 0x30, 0x43, 0x8a, 0x57, 0xba, 0x86, 0x3f, 0x7b, 0x66, 0xce, 0xf4, 0xec, 0x99, 0xf6, 0x1c, 0x9f, + 0x48, 0xde, 0x62, 0xaf, 0x1f, 0x22, 0xd7, 0x6c, 0xa7, 0xe4, 0x16, 0xce, 0x28, 0xd7, 0x6c, 0x77, + 0xe4, 0x6e, 0x7e, 0xf3, 0x07, 0x5f, 0x7e, 0xb2, 0xd6, 0x39, 0x94, 0x3f, 0xfe, 0xf2, 0x93, 0xb5, + 0x57, 0x78, 0x2f, 0xab, 0xdd, 0xe9, 0x66, 0x49, 0x8e, 0x3d, 0x2f, 0x20, 0xb3, 0xc3, 0x22, 0x5b, + 0xfc, 0x29, 0x47, 0xb3, 0x05, 0xbb, 0xa3, 0xce, 0x21, 0x5b, 0x5c, 0x85, 0xa9, 0x64, 0xf0, 0xc4, + 0xc9, 0x22, 0x11, 0x33, 0x03, 0xba, 0x1e, 0x27, 0x37, 0x35, 0xcb, 0x99, 0x9b, 0x9a, 0x1d, 0x16, + 0xa6, 0xfe, 0x65, 0x98, 0x9a, 0xca, 0xee, 0x8d, 0xff, 0x05, 0x53, 0x93, 0xa1, 0x3d, 0x72, 0x8a, + 0xd0, 0x1e, 0x3d, 0x6d, 0x68, 0x8f, 0xfd, 0x97, 0x42, 0x7b, 0xfc, 0x85, 0x86, 0x76, 0x76, 0xe3, + 0xf8, 0x7e, 0x67, 0x87, 0xc5, 0x7e, 0xff, 0xeb, 0x02, 0xbd, 0x26, 0xf7, 0x51, 0xb4, 0x93, 0x7c, + 0x6b, 0x91, 0xfa, 0x3f, 0x42, 0xa4, 0x66, 0x4e, 0x5d, 0xbc, 0xfd, 0xea, 0xb9, 0x13, 0x14, 0x06, + 0x77, 0x61, 0x32, 0xa0, 0x82, 0x93, 0x1d, 0xd5, 0xca, 0xe9, 0xde, 0xa5, 0x3a, 0x30, 0x11, 0x74, + 0x1b, 0x9b, 0xb0, 0x94, 0x7c, 0x7e, 0x92, 0x1f, 0xbc, 0x1d, 0xc6, 0x9d, 0x3f, 0x72, 0x26, 0xe7, + 0x2f, 0xba, 0x9d, 0x47, 0xab, 0xbd, 0xcf, 0xba, 0x7c, 0x7c, 0x23, 0xde, 0x22, 0x1b, 0x11, 0xdb, + 0x4a, 0xb6, 0xe1, 0x9a, 0x74, 0x1b, 0xe4, 0xfe, 0xe4, 0x35, 0xb9, 0x7c, 0x52, 0x6c, 0xc9, 0xaf, + 0x2e, 0xd0, 0x87, 0xcd, 0x01, 0xae, 0xd7, 0x5d, 0x14, 0x5f, 0xe0, 0x51, 0x80, 0x5d, 0x17, 0x05, + 0xe7, 0xbd, 0x23, 0xfb, 0x30, 0xdb, 0x44, 0x81, 0xe7, 0x84, 0x21, 0xed, 0xfa, 0xd1, 0xc7, 0x02, + 0xdd, 0x97, 0x8b, 0x1b, 0xaf, 0x76, 0xbd, 0x39, 0xb6, 0x5a, 0x51, 0xe3, 0xc3, 0x7b, 0x02, 0xce, + 0x9e, 0x16, 0x7a, 0xa1, 0x99, 0x19, 0x21, 0xe5, 0x5a, 0xfc, 0xd2, 0xe2, 0x7d, 0x38, 0xfe, 0xb9, + 0xf9, 0x66, 0xd6, 0x7b, 0x6b, 0x52, 0xef, 0x49, 0x4d, 0xd7, 0x34, 0x5a, 0x44, 0x4b, 0xe7, 0x62, + 0xdf, 0xad, 0x55, 0x60, 0x41, 0xca, 0x52, 0x99, 0x80, 0xd1, 0xb7, 0xf5, 0xad, 0x3b, 0x07, 0x85, + 0x21, 0x05, 0x60, 0x4c, 0xbf, 0x75, 0xff, 0xee, 0xbb, 0xb7, 0x0a, 0xb9, 0x8d, 0xdf, 0xcd, 0xc2, + 0xf0, 0x5e, 0x58, 0x57, 0x1e, 0xc0, 0x64, 0xb2, 0x77, 0x5b, 0xee, 0xb2, 0x3d, 0xdd, 0x62, 0x56, + 0xff, 0x6f, 0x00, 0x40, 0xf4, 0x55, 0xbf, 0x07, 0x17, 0x33, 0x7d, 0x61, 0x4d, 0xba, 0x34, 0x85, + 0x51, 0xd7, 0x06, 0x63, 0x84, 0x86, 0x07, 0x30, 0x99, 0x6c, 0x5e, 0x4a, 0xa9, 0x27, 0x00, 0x72, + 0xea, 0x92, 0x8e, 0xa2, 0xf2, 0x08, 0x0a, 0x5d, 0xdd, 0xc4, 0x97, 0xe5, 0x8b, 0xd3, 0x28, 0xf5, + 0xb5, 0x93, 0xa0, 0x84, 0x9e, 0x36, 0x5c, 0xea, 0xd1, 0x9a, 0x91, 0xba, 0x41, 0x8e, 0x55, 0x37, + 0x4e, 0x8e, 0x15, 0x9a, 0x31, 0xcc, 0xc9, 0xda, 0x2b, 0x3d, 0x3c, 0xd4, 0x05, 0x54, 0xab, 0x27, + 0x04, 0x0a, 0x85, 0xef, 0xc3, 0x74, 0xba, 0x6d, 0x72, 0x55, 0x26, 0x21, 0x05, 0x51, 0xff, 0x7f, + 0x20, 0x44, 0x88, 0x3f, 0x82, 0x05, 0xe9, 0x7b, 0xbf, 0x87, 0x23, 0xa5, 0xad, 0x81, 0x1e, 0x8e, + 0xec, 0xdb, 0x46, 0x50, 0x2c, 0x98, 0xc9, 0xb6, 0x10, 0x56, 0x64, 0x62, 0x32, 0x20, 0xf5, 0xda, + 0x09, 0x40, 0x42, 0xc9, 0xf7, 0xa1, 0xd8, 0xb3, 0x0d, 0xd0, 0x23, 0xe2, 0xe4, 0x68, 0xf5, 0xf5, + 0xd3, 0xa0, 0x85, 0xfe, 0x9f, 0xe6, 0x60, 0xa9, 0xff, 0x13, 0x7e, 0x5d, 0x26, 0xb7, 0xef, 0x12, + 0xf5, 0x8d, 0x53, 0x2f, 0x49, 0x46, 0xaf, 0xec, 0xc9, 0x2e, 0x8d, 0x5e, 0x09, 0x50, 0x1e, 0xbd, + 0x7d, 0xde, 0xe6, 0xca, 0x43, 0x98, 0x4a, 0xfd, 0xb1, 0x67, 0x59, 0x7e, 0xe4, 0x3a, 0x08, 0x75, + 0x75, 0x10, 0x42, 0xc8, 0xfe, 0x65, 0x0e, 0xca, 0x83, 0xfe, 0xa6, 0x7b, 0xa3, 0xb7, 0xaf, 0x7a, + 0x2e, 0x52, 0xdf, 0x3c, 0xc3, 0xa2, 0x64, 0xf6, 0xce, 0xb4, 0x22, 0xb4, 0x1e, 0xa1, 0x93, 0xc0, + 0xc8, 0xb3, 0xb7, 0xbc, 0x11, 0x41, 0x92, 0x6c, 0x57, 0x13, 0x42, 0x9a, 0x64, 0xb3, 0x28, 0x79, + 0x92, 0xed, 0xf5, 0x84, 0x21, 0x7a, 0xba, 0x9e, 0x2f, 0x2f, 0xf7, 0x3e, 0x7d, 0x83, 0xf4, 0xf4, + 0x7a, 0x3f, 0x10, 0x3d, 0x5d, 0x6f, 0x87, 0x97, 0x7b, 0x6f, 0xc1, 0x20, 0x3d, 0xbd, 0xea, 0x56, + 0x72, 0x69, 0xf4, 0xa8, 0x59, 0xa5, 0xde, 0x97, 0x63, 0xe5, 0xb9, 0xae, 0x7f, 0x79, 0xa6, 0xb4, + 0x60, 0x41, 0x5e, 0x9a, 0x49, 0x13, 0xb5, 0x14, 0xaa, 0xae, 0x9f, 0x18, 0x1a, 0xab, 0xdd, 0xbe, + 0xfd, 0xd9, 0xd3, 0x52, 0xee, 0xf3, 0xa7, 0xa5, 0xdc, 0x3f, 0x9e, 0x96, 0x72, 0x3f, 0x7f, 0x56, + 0x1a, 0xfa, 0xfc, 0x59, 0x69, 0xe8, 0xaf, 0xcf, 0x4a, 0x43, 0x0f, 0x37, 0x12, 0x55, 0xed, 0x3e, + 0x15, 0x7b, 0xfd, 0xb6, 0x59, 0x0b, 0xab, 0xbc, 0xb4, 0x3a, 0x5c, 0x7f, 0x23, 0x59, 0x5e, 0xd1, + 0x2a, 0xb7, 0x36, 0x46, 0xff, 0x33, 0xc5, 0x8d, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x29, + 0x1b, 0x37, 0x17, 0x22, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3566,6 +3570,15 @@ func (m *MsgRegisterHostZone) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.CommunityPoolTreasuryAddress) > 0 { + i -= len(m.CommunityPoolTreasuryAddress) + copy(dAtA[i:], m.CommunityPoolTreasuryAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.CommunityPoolTreasuryAddress))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x82 + } if m.LsmLiquidStakeEnabled { i-- if m.LsmLiquidStakeEnabled { @@ -4675,9 +4688,9 @@ func (m *MsgSetCommunityPoolRebate) MarshalToSizedBuffer(dAtA []byte) (int, erro var l int _ = l { - size := m.LiquidStakedAmount.Size() + size := m.LiquidStakedStTokenAmount.Size() i -= size - if _, err := m.LiquidStakedAmount.MarshalTo(dAtA[i:]); err != nil { + if _, err := m.LiquidStakedStTokenAmount.MarshalTo(dAtA[i:]); err != nil { return 0, err } i = encodeVarintTx(dAtA, i, uint64(size)) @@ -5012,6 +5025,10 @@ func (m *MsgRegisterHostZone) Size() (n int) { if m.LsmLiquidStakeEnabled { n += 2 } + l = len(m.CommunityPoolTreasuryAddress) + if l > 0 { + n += 2 + l + sovTx(uint64(l)) + } return n } @@ -5480,7 +5497,7 @@ func (m *MsgSetCommunityPoolRebate) Size() (n int) { } l = m.RebateRate.Size() n += 1 + l + sovTx(uint64(l)) - l = m.LiquidStakedAmount.Size() + l = m.LiquidStakedStTokenAmount.Size() n += 1 + l + sovTx(uint64(l)) return n } @@ -7002,6 +7019,38 @@ func (m *MsgRegisterHostZone) Unmarshal(dAtA []byte) error { } } m.LsmLiquidStakeEnabled = bool(v != 0) + case 16: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CommunityPoolTreasuryAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CommunityPoolTreasuryAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -10191,7 +10240,7 @@ func (m *MsgSetCommunityPoolRebate) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LiquidStakedAmount", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field LiquidStakedStTokenAmount", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -10219,7 +10268,7 @@ func (m *MsgSetCommunityPoolRebate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.LiquidStakedAmount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.LiquidStakedStTokenAmount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex From c7b0903b5383b1dfdde830f986a53077a7d3bc7d Mon Sep 17 00:00:00 2001 From: sampocs Date: Wed, 20 Mar 2024 14:12:12 -0500 Subject: [PATCH 09/13] renamed withdrawal balance callback (#1150) --- app/upgrades/v15/upgrades_test.go | 2 +- utils/utils.go | 2 +- x/stakeibc/keeper/delegation.go | 2 +- x/stakeibc/keeper/icqcallbacks.go | 4 +- ...> icqcallbacks_withdrawal_host_balance.go} | 18 ++--- ...callbacks_withdrawal_host_balance_test.go} | 68 +++++++++---------- .../icqcallbacks_withdrawal_reward_balance.go | 3 +- x/stakeibc/keeper/interchainqueries.go | 5 +- 8 files changed, 52 insertions(+), 52 deletions(-) rename x/stakeibc/keeper/{icqcallbacks_withdrawal_balance.go => icqcallbacks_withdrawal_host_balance.go} (90%) rename x/stakeibc/keeper/{icqcallbacks_withdrawal_balance_test.go => icqcallbacks_withdrawal_host_balance_test.go} (73%) diff --git a/app/upgrades/v15/upgrades_test.go b/app/upgrades/v15/upgrades_test.go index c0ceb3c5ae..d6c3095013 100644 --- a/app/upgrades/v15/upgrades_test.go +++ b/app/upgrades/v15/upgrades_test.go @@ -124,7 +124,7 @@ func (s *UpgradeTestSuite) SetupQueriesBeforeUpgrade() func() { {Id: "1", CallbackId: stakeibckeeper.ICQCallbackID_Validator}, {Id: "2", CallbackId: stakeibckeeper.ICQCallbackID_Delegation}, // deleted {Id: "3", CallbackId: stakeibckeeper.ICQCallbackID_Delegation}, // deleted - {Id: "4", CallbackId: stakeibckeeper.ICQCallbackID_WithdrawalBalance}, + {Id: "4", CallbackId: stakeibckeeper.ICQCallbackID_WithdrawalHostBalance}, } expectedQueriesAfterUpgrade := []string{"1", "4"} diff --git a/utils/utils.go b/utils/utils.go index 501de7450c..be7a1f57cb 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -258,7 +258,7 @@ func LogICACallbackStatusWithHostZone(chainId string, callbackId string, status // Returns a log string with a chain Id and icqcallback as a prefix // Ex: // -// | COSMOSHUB-4 | WITHDRAWALBALANCE ICQCALLBACK | string +// | COSMOSHUB-4 | WITHDRAWALHOSTBALANCE ICQCALLBACK | string func LogICQCallbackWithHostZone(chainId string, callbackId string, s string, a ...any) string { return logCallbackWithHostZone(chainId, callbackId, "ICQCALLBACK", s, a...) } diff --git a/x/stakeibc/keeper/delegation.go b/x/stakeibc/keeper/delegation.go index a81fe230f4..7eddb10f1c 100644 --- a/x/stakeibc/keeper/delegation.go +++ b/x/stakeibc/keeper/delegation.go @@ -183,7 +183,7 @@ func (k Keeper) ReinvestRewards(ctx sdk.Context) { } k.Logger(ctx).Info(utils.LogWithHostZone(hostZone.ChainId, "BlockTime for host zone: %d", blockTime)) - err = k.UpdateWithdrawalBalance(ctx, hostZone) + err = k.SubmitWithdrawalHostBalanceICQ(ctx, hostZone) if err != nil { k.Logger(ctx).Error(fmt.Sprintf("Error updating withdrawal balance for host zone %s: %s", hostZone.ConnectionId, err.Error())) continue diff --git a/x/stakeibc/keeper/icqcallbacks.go b/x/stakeibc/keeper/icqcallbacks.go index 880226cace..89e6a3029a 100644 --- a/x/stakeibc/keeper/icqcallbacks.go +++ b/x/stakeibc/keeper/icqcallbacks.go @@ -7,7 +7,7 @@ import ( ) const ( - ICQCallbackID_WithdrawalBalance = "withdrawalbalance" + ICQCallbackID_WithdrawalHostBalance = "withdrawalbalance" ICQCallbackID_FeeBalance = "feebalance" ICQCallbackID_Delegation = "delegation" ICQCallbackID_Validator = "validator" @@ -49,7 +49,7 @@ func (c ICQCallbacks) AddICQCallback(id string, fn interface{}) icqtypes.QueryCa func (c ICQCallbacks) RegisterICQCallbacks() icqtypes.QueryCallbacks { return c. - AddICQCallback(ICQCallbackID_WithdrawalBalance, ICQCallback(WithdrawalBalanceCallback)). + AddICQCallback(ICQCallbackID_WithdrawalHostBalance, ICQCallback(WithdrawalHostBalanceCallback)). AddICQCallback(ICQCallbackID_FeeBalance, ICQCallback(FeeBalanceCallback)). AddICQCallback(ICQCallbackID_Delegation, ICQCallback(DelegatorSharesCallback)). AddICQCallback(ICQCallbackID_Validator, ICQCallback(ValidatorSharesToTokensRateCallback)). diff --git a/x/stakeibc/keeper/icqcallbacks_withdrawal_balance.go b/x/stakeibc/keeper/icqcallbacks_withdrawal_host_balance.go similarity index 90% rename from x/stakeibc/keeper/icqcallbacks_withdrawal_balance.go rename to x/stakeibc/keeper/icqcallbacks_withdrawal_host_balance.go index 49aefa89f0..4cba47f96b 100644 --- a/x/stakeibc/keeper/icqcallbacks_withdrawal_balance.go +++ b/x/stakeibc/keeper/icqcallbacks_withdrawal_host_balance.go @@ -15,14 +15,14 @@ import ( "github.com/Stride-Labs/stride/v19/x/stakeibc/types" ) -// WithdrawalBalanceCallback is a callback handler for WithdrawalBalance queries. -// The query response will return the withdrawal account balance +// WithdrawalHostBalanceCallback is a callback handler for WithdrawalBalance queries. +// The query response will return the withdrawal account balance for the native denom (i.e. "host denom") // If the balance is non-zero, ICA MsgSends are submitted to transfer from the withdrawal account // to the delegation account (for reinvestment) and fee account (for commission) // // Note: for now, to get proofs in your ICQs, you need to query the entire store on the host zone! e.g. "store/bank/key" -func WithdrawalBalanceCallback(k Keeper, ctx sdk.Context, args []byte, query icqtypes.Query) error { - k.Logger(ctx).Info(utils.LogICQCallbackWithHostZone(query.ChainId, ICQCallbackID_WithdrawalBalance, +func WithdrawalHostBalanceCallback(k Keeper, ctx sdk.Context, args []byte, query icqtypes.Query) error { + k.Logger(ctx).Info(utils.LogICQCallbackWithHostZone(query.ChainId, ICQCallbackID_WithdrawalHostBalance, "Starting withdrawal balance callback, QueryId: %vs, QueryType: %s, Connection: %s", query.Id, query.QueryType, query.ConnectionId)) // Confirm host exists @@ -37,12 +37,12 @@ func WithdrawalBalanceCallback(k Keeper, ctx sdk.Context, args []byte, query icq if err != nil { return errorsmod.Wrap(err, "unable to determine balance from query response") } - k.Logger(ctx).Info(utils.LogICQCallbackWithHostZone(chainId, ICQCallbackID_WithdrawalBalance, + k.Logger(ctx).Info(utils.LogICQCallbackWithHostZone(chainId, ICQCallbackID_WithdrawalHostBalance, "Query response - Withdrawal Balance: %v %s", withdrawalBalanceAmount, hostZone.HostDenom)) // Confirm the balance is greater than zero if withdrawalBalanceAmount.LTE(sdkmath.ZeroInt()) { - k.Logger(ctx).Info(utils.LogICQCallbackWithHostZone(chainId, ICQCallbackID_WithdrawalBalance, + k.Logger(ctx).Info(utils.LogICQCallbackWithHostZone(chainId, ICQCallbackID_WithdrawalHostBalance, "No balance to transfer for address: %s, balance: %v", hostZone.WithdrawalIcaAddress, withdrawalBalanceAmount)) return nil } @@ -75,7 +75,7 @@ func WithdrawalBalanceCallback(k Keeper, ctx sdk.Context, args []byte, query icq ToAddress: hostZone.FeeIcaAddress, Amount: sdk.NewCoins(feeCoin), }) - k.Logger(ctx).Info(utils.LogICQCallbackWithHostZone(chainId, ICQCallbackID_WithdrawalBalance, + k.Logger(ctx).Info(utils.LogICQCallbackWithHostZone(chainId, ICQCallbackID_WithdrawalHostBalance, "Preparing MsgSends of %v from the withdrawal account to the fee account (for commission)", feeCoin.String())) } if reinvestCoin.Amount.GT(sdk.ZeroInt()) { @@ -84,7 +84,7 @@ func WithdrawalBalanceCallback(k Keeper, ctx sdk.Context, args []byte, query icq ToAddress: hostZone.DelegationIcaAddress, Amount: sdk.NewCoins(reinvestCoin), }) - k.Logger(ctx).Info(utils.LogICQCallbackWithHostZone(chainId, ICQCallbackID_WithdrawalBalance, + k.Logger(ctx).Info(utils.LogICQCallbackWithHostZone(chainId, ICQCallbackID_WithdrawalHostBalance, "Preparing MsgSends of %v from the withdrawal account to the delegation account (for reinvestment)", reinvestCoin.String())) } @@ -93,7 +93,7 @@ func WithdrawalBalanceCallback(k Keeper, ctx sdk.Context, args []byte, query icq ReinvestAmount: reinvestCoin, HostZoneId: hostZone.ChainId, } - k.Logger(ctx).Info(utils.LogICQCallbackWithHostZone(chainId, ICQCallbackID_WithdrawalBalance, "Marshalling ReinvestCallback args: %v", reinvestCallback)) + k.Logger(ctx).Info(utils.LogICQCallbackWithHostZone(chainId, ICQCallbackID_WithdrawalHostBalance, "Marshalling ReinvestCallback args: %v", reinvestCallback)) marshalledCallbackArgs, err := k.MarshalReinvestCallbackArgs(ctx, reinvestCallback) if err != nil { return err diff --git a/x/stakeibc/keeper/icqcallbacks_withdrawal_balance_test.go b/x/stakeibc/keeper/icqcallbacks_withdrawal_host_balance_test.go similarity index 73% rename from x/stakeibc/keeper/icqcallbacks_withdrawal_balance_test.go rename to x/stakeibc/keeper/icqcallbacks_withdrawal_host_balance_test.go index f920b54bde..11298559cf 100644 --- a/x/stakeibc/keeper/icqcallbacks_withdrawal_balance_test.go +++ b/x/stakeibc/keeper/icqcallbacks_withdrawal_host_balance_test.go @@ -39,7 +39,7 @@ func (s *KeeperTestSuite) CreateBalanceQueryResponse(amount int64, denom string) return coinBz } -func (s *KeeperTestSuite) SetupWithdrawalBalanceCallbackTest() WithdrawalBalanceICQCallbackTestCase { +func (s *KeeperTestSuite) SetupWithdrawalHostBalanceCallbackTest() WithdrawalBalanceICQCallbackTestCase { delegationAccountOwner := fmt.Sprintf("%s.%s", HostChainId, "DELEGATION") s.CreateICAChannel(delegationAccountOwner) delegationAddress := s.IcaAddresses[delegationAccountOwner] @@ -97,8 +97,8 @@ func (s *KeeperTestSuite) SetupWithdrawalBalanceCallbackTest() WithdrawalBalance } } -func (s *KeeperTestSuite) TestWithdrawalBalanceCallback_Successful() { - tc := s.SetupWithdrawalBalanceCallbackTest() +func (s *KeeperTestSuite) TestWithdrawalHostBalanceCallback_Successful() { + tc := s.SetupWithdrawalHostBalanceCallbackTest() // Get the sequence number before the ICA is submitted to confirm it incremented withdrawalChannel := tc.initialState.withdrawalChannel @@ -109,7 +109,7 @@ func (s *KeeperTestSuite) TestWithdrawalBalanceCallback_Successful() { s.Require().True(found, "sequence number not found before reinvestment") // Call the ICQ callback - err := keeper.WithdrawalBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.validArgs.callbackArgs, tc.validArgs.query) + err := keeper.WithdrawalHostBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.validArgs.callbackArgs, tc.validArgs.query) s.Require().NoError(err) // Confirm ICA reinvestment callback data was stored @@ -131,105 +131,105 @@ func (s *KeeperTestSuite) TestWithdrawalBalanceCallback_Successful() { s.Require().Equal(endSequence, startSequence+1, "sequence number after reinvestment") } -func (s *KeeperTestSuite) TestWithdrawalBalanceCallback_EmptyCallbackArgs() { - tc := s.SetupWithdrawalBalanceCallbackTest() +func (s *KeeperTestSuite) TestWithdrawalHostBalanceCallback_EmptyCallbackArgs() { + tc := s.SetupWithdrawalHostBalanceCallbackTest() // Replace the query response an empty byte array (this happens when the account has not been registered yet) emptyCallbackArgs := []byte{} - err := keeper.WithdrawalBalanceCallback(s.App.StakeibcKeeper, s.Ctx, emptyCallbackArgs, tc.validArgs.query) + err := keeper.WithdrawalHostBalanceCallback(s.App.StakeibcKeeper, s.Ctx, emptyCallbackArgs, tc.validArgs.query) s.Require().NoError(err) // Confirm revinvestment callback was not created s.Require().Len(s.App.IcacallbacksKeeper.GetAllCallbackData(s.Ctx), 0, "number of callbacks found") } -func (s *KeeperTestSuite) TestWithdrawalBalanceCallback_ZeroBalance() { - tc := s.SetupWithdrawalBalanceCallbackTest() +func (s *KeeperTestSuite) TestWithdrawalHostBalanceCallback_ZeroBalance() { + tc := s.SetupWithdrawalHostBalanceCallbackTest() // Replace the query response with a coin that has a nil amount tc.validArgs.callbackArgs = s.CreateBalanceQueryResponse(0, Atom) - err := keeper.WithdrawalBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.validArgs.callbackArgs, tc.validArgs.query) + err := keeper.WithdrawalHostBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.validArgs.callbackArgs, tc.validArgs.query) s.Require().NoError(err) // Confirm revinvestment callback was not created s.Require().Len(s.App.IcacallbacksKeeper.GetAllCallbackData(s.Ctx), 0, "number of callbacks found") } -func (s *KeeperTestSuite) TestWithdrawalBalanceCallback_ZeroBalanceImplied() { - tc := s.SetupWithdrawalBalanceCallbackTest() +func (s *KeeperTestSuite) TestWithdrawalHostBalanceCallback_ZeroBalanceImplied() { + tc := s.SetupWithdrawalHostBalanceCallbackTest() // Replace the query response with a coin that has a nil amount coin := sdk.Coin{} coinBz := s.App.RecordsKeeper.Cdc.MustMarshal(&coin) tc.validArgs.callbackArgs = coinBz - err := keeper.WithdrawalBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.validArgs.callbackArgs, tc.validArgs.query) + err := keeper.WithdrawalHostBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.validArgs.callbackArgs, tc.validArgs.query) s.Require().NoError(err) // Confirm revinvestment callback was not created s.Require().Len(s.App.IcacallbacksKeeper.GetAllCallbackData(s.Ctx), 0, "number of callbacks found") } -func (s *KeeperTestSuite) TestWithdrawalBalanceCallback_HostZoneNotFound() { - tc := s.SetupWithdrawalBalanceCallbackTest() +func (s *KeeperTestSuite) TestWithdrawalHostBalanceCallback_HostZoneNotFound() { + tc := s.SetupWithdrawalHostBalanceCallbackTest() // Submit callback with incorrect host zone invalidQuery := tc.validArgs.query invalidQuery.ChainId = "fake_host_zone" - err := keeper.WithdrawalBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.validArgs.callbackArgs, invalidQuery) + err := keeper.WithdrawalHostBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.validArgs.callbackArgs, invalidQuery) s.Require().EqualError(err, "no registered zone for queried chain ID (fake_host_zone): host zone not found") } -func (s *KeeperTestSuite) TestWithdrawalBalanceCallback_InvalidArgs() { - tc := s.SetupWithdrawalBalanceCallbackTest() +func (s *KeeperTestSuite) TestWithdrawalHostBalanceCallback_InvalidArgs() { + tc := s.SetupWithdrawalHostBalanceCallbackTest() // Submit callback with invalid callback args (so that it can't unmarshal into a coin) invalidArgs := []byte("random bytes") - err := keeper.WithdrawalBalanceCallback(s.App.StakeibcKeeper, s.Ctx, invalidArgs, tc.validArgs.query) + err := keeper.WithdrawalHostBalanceCallback(s.App.StakeibcKeeper, s.Ctx, invalidArgs, tc.validArgs.query) s.Require().ErrorContains(err, "unable to determine balance from query response") } -func (s *KeeperTestSuite) TestWithdrawalBalanceCallback_NoWithdrawalAccount() { - tc := s.SetupWithdrawalBalanceCallbackTest() +func (s *KeeperTestSuite) TestWithdrawalHostBalanceCallback_NoWithdrawalAccount() { + tc := s.SetupWithdrawalHostBalanceCallbackTest() // Remove the withdrawal account badHostZone := tc.initialState.hostZone badHostZone.WithdrawalIcaAddress = "" s.App.StakeibcKeeper.SetHostZone(s.Ctx, badHostZone) - err := keeper.WithdrawalBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.validArgs.callbackArgs, tc.validArgs.query) + err := keeper.WithdrawalHostBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.validArgs.callbackArgs, tc.validArgs.query) s.Require().EqualError(err, "no withdrawal account found for GAIA: ICA acccount not found on host zone") } -func (s *KeeperTestSuite) TestWithdrawalBalanceCallback_NoDelegationAccount() { - tc := s.SetupWithdrawalBalanceCallbackTest() +func (s *KeeperTestSuite) TestWithdrawalHostBalanceCallback_NoDelegationAccount() { + tc := s.SetupWithdrawalHostBalanceCallbackTest() // Remove the delegation account badHostZone := tc.initialState.hostZone badHostZone.DelegationIcaAddress = "" s.App.StakeibcKeeper.SetHostZone(s.Ctx, badHostZone) - err := keeper.WithdrawalBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.validArgs.callbackArgs, tc.validArgs.query) + err := keeper.WithdrawalHostBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.validArgs.callbackArgs, tc.validArgs.query) s.Require().EqualError(err, "no delegation account found for GAIA: ICA acccount not found on host zone") } -func (s *KeeperTestSuite) TestWithdrawalBalanceCallback_NoFeeAccount() { - tc := s.SetupWithdrawalBalanceCallbackTest() +func (s *KeeperTestSuite) TestWithdrawalHostBalanceCallback_NoFeeAccount() { + tc := s.SetupWithdrawalHostBalanceCallbackTest() // Remove the fee account badHostZone := tc.initialState.hostZone badHostZone.FeeIcaAddress = "" s.App.StakeibcKeeper.SetHostZone(s.Ctx, badHostZone) - err := keeper.WithdrawalBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.validArgs.callbackArgs, tc.validArgs.query) + err := keeper.WithdrawalHostBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.validArgs.callbackArgs, tc.validArgs.query) s.Require().EqualError(err, "no fee account found for GAIA: ICA acccount not found on host zone") } -func (s *KeeperTestSuite) TestWithdrawalBalanceCallback_FailedToCheckForRebate() { - tc := s.SetupWithdrawalBalanceCallbackTest() +func (s *KeeperTestSuite) TestWithdrawalHostBalanceCallback_FailedToCheckForRebate() { + tc := s.SetupWithdrawalHostBalanceCallbackTest() // Add a rebate to the host zone - since there are no stTokens in supply, the test will fail hostZone := s.MustGetHostZone(HostChainId) @@ -239,19 +239,19 @@ func (s *KeeperTestSuite) TestWithdrawalBalanceCallback_FailedToCheckForRebate() } s.App.StakeibcKeeper.SetHostZone(s.Ctx, hostZone) - err := keeper.WithdrawalBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.validArgs.callbackArgs, tc.validArgs.query) + err := keeper.WithdrawalHostBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.validArgs.callbackArgs, tc.validArgs.query) s.Require().ErrorContains(err, "unable to split reward amount into fee and reinvest amounts") } -func (s *KeeperTestSuite) TestWithdrawalBalanceCallback_FailedSubmitTx() { - tc := s.SetupWithdrawalBalanceCallbackTest() +func (s *KeeperTestSuite) TestWithdrawalHostBalanceCallback_FailedSubmitTx() { + tc := s.SetupWithdrawalHostBalanceCallbackTest() // Remove connectionId from host zone so the ICA tx fails badHostZone := tc.initialState.hostZone badHostZone.ConnectionId = "connection-X" s.App.StakeibcKeeper.SetHostZone(s.Ctx, badHostZone) - err := keeper.WithdrawalBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.validArgs.callbackArgs, tc.validArgs.query) + err := keeper.WithdrawalHostBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.validArgs.callbackArgs, tc.validArgs.query) s.Require().ErrorContains(err, "Failed to SubmitTxs") s.Require().ErrorContains(err, "connection connection-X not found") } diff --git a/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance.go b/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance.go index 8ce18ad977..0fdbf05e04 100644 --- a/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance.go +++ b/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance.go @@ -15,7 +15,8 @@ import ( ) // WithdrawalRewardBalanceCallback is a callback handler for WithdrawalRewardBalance queries. -// The query response will return the withdrawal account balance for a specific (foreign ibc) denom +// The query response will return the withdrawal account balance for the reward denom in the case +// of a host zone with a trade route (e.g. USDC in the case of the dYdX trade route) // If the balance is non-zero, ICA MsgSends are submitted to transfer the discovered balance to the tradeZone // // Note: for now, to get proofs in your ICQs, you need to query the entire store on the host zone! e.g. "store/bank/key" diff --git a/x/stakeibc/keeper/interchainqueries.go b/x/stakeibc/keeper/interchainqueries.go index 6f0b298766..5c455c1b88 100644 --- a/x/stakeibc/keeper/interchainqueries.go +++ b/x/stakeibc/keeper/interchainqueries.go @@ -186,9 +186,8 @@ func (k Keeper) SubmitCalibrationICQ(ctx sdk.Context, hostZone types.HostZone, v return nil } -// TODO [cleanup]: Rename to SubmitWithdrawalBalanceICQ // Submits an ICQ for the withdrawal account balance -func (k Keeper) UpdateWithdrawalBalance(ctx sdk.Context, hostZone types.HostZone) error { +func (k Keeper) SubmitWithdrawalHostBalanceICQ(ctx sdk.Context, hostZone types.HostZone) error { k.Logger(ctx).Info(utils.LogWithHostZone(hostZone.ChainId, "Submitting ICQ for withdrawal account balance")) // Get the withdrawal account address from the host zone @@ -219,7 +218,7 @@ func (k Keeper) UpdateWithdrawalBalance(ctx sdk.Context, hostZone types.HostZone QueryType: icqtypes.BANK_STORE_QUERY_WITH_PROOF, RequestData: queryData, CallbackModule: types.ModuleName, - CallbackId: ICQCallbackID_WithdrawalBalance, + CallbackId: ICQCallbackID_WithdrawalHostBalance, TimeoutDuration: timeoutDuration, TimeoutPolicy: icqtypes.TimeoutPolicy_REJECT_QUERY_RESPONSE, } From 2f8e27df60f414edbd609ad4ffc61131bc0666c6 Mon Sep 17 00:00:00 2001 From: sampocs Date: Wed, 20 Mar 2024 23:42:56 -0500 Subject: [PATCH 10/13] rebate integration tests (#1152) --- deps/osmosis | 2 +- dockernet/config/ica_host.json | 2 + .../scripts/community-pool-staking/README.md | 12 +++ .../community-pool-staking/add_trade_route.sh | 27 +++++- .../scripts/community-pool-staking/rebate.sh | 9 ++ .../scripts/community-pool-staking/trade.sh | 25 +++++ dockernet/src/create_logs.sh | 92 ++++++++++--------- dockernet/src/init_chain.sh | 2 +- dockernet/src/register_host.sh | 7 +- dockernet/start_network.sh | 2 + .../icqcallbacks_withdrawal_reward_balance.go | 2 +- x/stakeibc/keeper/reward_converter.go | 12 +-- 12 files changed, 138 insertions(+), 56 deletions(-) create mode 100644 dockernet/scripts/community-pool-staking/rebate.sh create mode 100644 dockernet/scripts/community-pool-staking/trade.sh diff --git a/deps/osmosis b/deps/osmosis index 3e2c326301..30532bd83e 160000 --- a/deps/osmosis +++ b/deps/osmosis @@ -1 +1 @@ -Subproject commit 3e2c326301aff138214c1d25630edb360459c0fd +Subproject commit 30532bd83ebac4e8985fb9d4ead91bc2722810fb diff --git a/dockernet/config/ica_host.json b/dockernet/config/ica_host.json index 0017667db7..3ca3c342f8 100644 --- a/dockernet/config/ica_host.json +++ b/dockernet/config/ica_host.json @@ -19,6 +19,8 @@ "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress", "/cosmos.distribution.v1beta1.MsgFundCommunityPool", + "/cosmos.authz.v1beta1.MsgGrant", + "/cosmos.authz.v1beta1.MsgRevoke", "/ibc.applications.transfer.v1.MsgTransfer", "/cosmwasm.wasm.v1.MsgExecuteContract", "/cosmwasm.wasm.v1.MsgInstantiateContract", diff --git a/dockernet/scripts/community-pool-staking/README.md b/dockernet/scripts/community-pool-staking/README.md index 95b2beae21..3bf8a1b9e3 100644 --- a/dockernet/scripts/community-pool-staking/README.md +++ b/dockernet/scripts/community-pool-staking/README.md @@ -45,7 +45,19 @@ bash dockernet/scripts/community-pool-staking/create_pool.sh ```bash bash dockernet/scripts/community-pool-staking/add_trade_route.sh ``` +* Liquid stake to create TVL +```bash +bash dockernet/scripts/community-pool-staking/stake.sh +``` * Finally, test the reinvestment flow by sending USDC to the withdrawal address. View `logs/balances.log` to watch the funds traverse the different accounts ```bash bash dockernet/scripts/community-pool-staking/reinvest.sh ``` +* To register a rebate, run the following script. +```bash +bash dockernet/scripts/community-pool-staking/rebate.sh +``` +* Then trigger reinvestment again. This time, you should notice USDC goes straight from the withdrawal account to the relevant community pool account. For Gaia, this account is the standard community pool, and for dYdX, the account is the community pool treasury. +```bash +bash dockernet/scripts/community-pool-staking/reinvest.sh +``` \ No newline at end of file diff --git a/dockernet/scripts/community-pool-staking/add_trade_route.sh b/dockernet/scripts/community-pool-staking/add_trade_route.sh index 173b7a9647..0b9b02ca87 100644 --- a/dockernet/scripts/community-pool-staking/add_trade_route.sh +++ b/dockernet/scripts/community-pool-staking/add_trade_route.sh @@ -5,8 +5,10 @@ source ${SCRIPT_DIR}/../../config.sh HOST_CHAIN=$REWARD_CONVERTER_HOST_ZONE HOST_VAL_ADDRESS=$(${HOST_CHAIN}_ADDRESS) -HOST_CHAIN_ID=$(GET_VAR_VALUE ${HOST_CHAIN}_CHAIN_ID) -HOST_DENOM=$(GET_VAR_VALUE ${HOST_CHAIN}_DENOM) +HOST_MAIN_CMD=$(GET_VAR_VALUE ${HOST_CHAIN}_MAIN_CMD) +HOST_CHAIN_ID=$(GET_VAR_VALUE ${HOST_CHAIN}_CHAIN_ID) +HOST_VAL_PREFIX=$(GET_VAR_VALUE ${HOST_CHAIN}_VAL_PREFIX) +HOST_DENOM=$(GET_VAR_VALUE ${HOST_CHAIN}_DENOM) GAS="--gas-prices 0.1ustrd --gas auto --gas-adjustment 1.3" @@ -21,6 +23,10 @@ host_to_noble_client=$(GET_CLIENT_ID_FROM_CHAIN_ID $HOST_CHAIN NOBLE) host_to_noble_connection=$(GET_CONNECTION_ID_FROM_CLIENT_ID $HOST_CHAIN $host_to_noble_client) host_to_noble_channel=$(GET_TRANSFER_CHANNEL_ID_FROM_CONNECTION_ID $HOST_CHAIN $host_to_noble_connection) +host_to_osmo_client=$(GET_CLIENT_ID_FROM_CHAIN_ID $HOST_CHAIN OSMO) +host_to_osmo_connection=$(GET_CONNECTION_ID_FROM_CLIENT_ID $HOST_CHAIN $host_to_osmo_client) +host_to_osmo_channel=$(GET_TRANSFER_CHANNEL_ID_FROM_CONNECTION_ID $HOST_CHAIN $host_to_osmo_connection) + noble_to_host_client=$(GET_CLIENT_ID_FROM_CHAIN_ID NOBLE $HOST_CHAIN) noble_to_host_connection=$(GET_CONNECTION_ID_FROM_CLIENT_ID NOBLE $noble_to_host_client) noble_to_host_channel=$(GET_TRANSFER_CHANNEL_ID_FROM_CONNECTION_ID NOBLE $noble_to_host_connection) @@ -60,11 +66,26 @@ echo " Client: $osmo_to_host_client" echo " Connection: $osmo_to_host_connection" echo " Transfer Channel: $osmo_to_host_channel" -echo -e "\nTransferring $USDC_DENOM to $HOST_DENOM to create ibc denom..." +echo -e "\n$HOST_CHAIN -> OSMO:" +echo " Client: $host_to_osmo_client" +echo " Connection: $host_to_osmo_connection" +echo " Transfer Channel: $host_to_osmo_channel" + +echo -e "\nTransferring $USDC_DENOM to $HOST_CHAIN to create ibc denom..." $NOBLE_MAIN_CMD tx ibc-transfer transfer transfer $noble_to_host_channel $HOST_VAL_ADDRESS 10000${USDC_DENOM} \ --from ${NOBLE_VAL_PREFIX}1 -y | TRIM_TX sleep 15 +echo -e "\nTransferring $USDC_DENOM to OSMO to create ibc denom..." +$NOBLE_MAIN_CMD tx ibc-transfer transfer transfer $noble_to_osmo_channel $(OSMO_ADDRESS) 10000${USDC_DENOM} \ + --from ${NOBLE_VAL_PREFIX}1 -y | TRIM_TX +sleep 15 + +echo -e "\nTransferring $HOST_DENOM to OSMO to create ibc denom..." +$HOST_MAIN_CMD tx ibc-transfer transfer transfer $host_to_osmo_channel $(OSMO_ADDRESS) 10000000${HOST_DENOM} \ + --from ${HOST_VAL_PREFIX}1 -y | TRIM_TX +sleep 15 + echo -e "\nDetermining IBC Denoms..." usdc_denom_on_host=$(GET_IBC_DENOM $HOST_CHAIN_ID $host_to_noble_channel $USDC_DENOM) usdc_denom_on_osmo=$(GET_IBC_DENOM OSMO $osmo_to_noble_channel $USDC_DENOM) diff --git a/dockernet/scripts/community-pool-staking/rebate.sh b/dockernet/scripts/community-pool-staking/rebate.sh new file mode 100644 index 0000000000..1bfad1c96f --- /dev/null +++ b/dockernet/scripts/community-pool-staking/rebate.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -eu +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +source ${SCRIPT_DIR}/../../config.sh + +HOST_CHAIN=$REWARD_CONVERTER_HOST_ZONE +HOST_CHAIN_ID=$(GET_VAR_VALUE ${HOST_CHAIN}_CHAIN_ID) + +$STRIDE_MAIN_CMD tx stakeibc set-rebate $HOST_CHAIN_ID 0.25 100000 --from admin -y \ No newline at end of file diff --git a/dockernet/scripts/community-pool-staking/trade.sh b/dockernet/scripts/community-pool-staking/trade.sh new file mode 100644 index 0000000000..2996dce7c6 --- /dev/null +++ b/dockernet/scripts/community-pool-staking/trade.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -eu +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +source ${SCRIPT_DIR}/../../config.sh + +TRADE_AMOUNT=997500 + +trade_account=$($STRIDE_MAIN_CMD q stakeibc list-trade-routes | grep trade_account -A 3 | grep address | awk '{print $2}') +host_denom_on_trade=$($STRIDE_MAIN_CMD q stakeibc list-trade-routes | grep host_denom_on_trade | awk '{print $2}') +reward_denom_on_trade=$($STRIDE_MAIN_CMD q stakeibc list-trade-routes | grep reward_denom_on_trade | awk '{print $2}') + +echo "Granting authz permissions..." +$STRIDE_MAIN_CMD tx stakeibc toggle-trade-controller $OSMO_CHAIN_ID grant $(OSMO_ADDRESS) --from admin -y +sleep 15 + +tx_file=${STATE}/${OSMO_NODE_PREFIX}1/swap_tx.json +$OSMO_MAIN_CMD tx gamm swap-exact-amount-in ${TRADE_AMOUNT}${reward_denom_on_trade} 1 \ + --swap-route-pool-ids 1 --swap-route-denoms $host_denom_on_trade \ + --from $trade_account --generate-only > $tx_file +sleep 5 + +echo "Executing swap through authz..." +$OSMO_MAIN_CMD tx authz exec $tx_file --from ${OSMO_VAL_PREFIX}1 -y | TRIM_TX +sleep 1 +rm -f $tx_file \ No newline at end of file diff --git a/dockernet/src/create_logs.sh b/dockernet/src/create_logs.sh index 0c22c43282..f89d62ec52 100755 --- a/dockernet/src/create_logs.sh +++ b/dockernet/src/create_logs.sh @@ -88,53 +88,57 @@ while true; do print_header "TRADE ROUTES" $state $STRIDE_MAIN_CMD q stakeibc list-trade-routes >> $state - print_separator "STAKETIA" $state - - print_header "HOST ZONE" $state - $STRIDE_MAIN_CMD q staketia host-zone >> $state - print_header "DELEGATION RECORDS" $state - $STRIDE_MAIN_CMD q staketia delegation-records >> $state - print_header "UNBONDING RECORDS" $state - $STRIDE_MAIN_CMD q staketia unbonding-records >> $state - print_header "REDEMPTION RECORDS" $state - $STRIDE_MAIN_CMD q staketia redemption-records >> $state - print_header "SLASH RECORDS" $state - $STRIDE_MAIN_CMD q staketia slash-records >> $state + host_chain="${HOST_CHAINS[0]}" + if [[ "$host_chain" == "GAIA" ]]; then + print_separator "STAKETIA" $state + + print_header "HOST ZONE" $state + $STRIDE_MAIN_CMD q staketia host-zone >> $state + print_header "DELEGATION RECORDS" $state + $STRIDE_MAIN_CMD q staketia delegation-records >> $state + print_header "UNBONDING RECORDS" $state + $STRIDE_MAIN_CMD q staketia unbonding-records >> $state + print_header "REDEMPTION RECORDS" $state + $STRIDE_MAIN_CMD q staketia redemption-records >> $state + print_header "SLASH RECORDS" $state + $STRIDE_MAIN_CMD q staketia slash-records >> $state + fi # Log stride stakeibc balances print_separator "VALIDATORS" $balances - host_chain="${HOST_CHAINS[0]}" host_val_address="$(${host_chain}_ADDRESS)" host_cmd=$(GET_VAR_VALUE ${host_chain}_MAIN_CMD) print_stride_balance $(STRIDE_ADDRESS) "STRIDE" print_host_balance $host_chain $host_val_address $host_chain - # Log stride staketia balances - print_separator "STAKETIA STRIDE" $balances - - deposit_address=$($STRIDE_MAIN_CMD keys show -a deposit) - redemption_address=$($STRIDE_MAIN_CMD keys show -a redemption) - claim_address=$($STRIDE_MAIN_CMD keys show -a claim) - fee_address=$($STRIDE_MAIN_CMD q auth module-account staketia_fee_address | grep "address:" | awk '{print $2}') - - print_stride_balance $deposit_address "DEPOSIT" - print_stride_balance $redemption_address "REDEMPTION" - print_stride_balance $claim_address "CLAIM" - print_stride_balance $fee_address "FEE" - - # Log staketia balance on host chain - print_separator "STAKETIA HOST" $balances - print_host_balance "$host_chain" $DELEGATION_ADDRESS "DELEGATION CONTROLLER" - print_host_balance "$host_chain" $REWARD_ADDRESS "REWARD CONTROLLER" - - # Log staketia delegations/undelegations - print_separator "STAKETIA STAKING" $balances - delegation_address=$($STRIDE_MAIN_CMD q staketia host-zone | grep "delegation_address" | awk '{print $2}') - - print_header "DELEGATIONS $host_chain" $balances - $host_cmd q staking delegations $delegation_address | grep -vE "pagination|total|next_key" >> $balances - print_header "UNBONDING-DELEGATIONS $host_chain" $balances - $host_cmd q staking unbonding-delegations $delegation_address | grep -vE "pagination|total|next_key" >> $balances + if [[ "$host_chain" == "GAIA" ]]; then + # Log stride staketia balances + print_separator "STAKETIA STRIDE" $balances + + deposit_address=$($STRIDE_MAIN_CMD keys show -a deposit) + redemption_address=$($STRIDE_MAIN_CMD keys show -a redemption) + claim_address=$($STRIDE_MAIN_CMD keys show -a claim) + fee_address=$($STRIDE_MAIN_CMD q auth module-account staketia_fee_address | grep "address:" | awk '{print $2}') + + print_stride_balance $deposit_address "DEPOSIT" + print_stride_balance $redemption_address "REDEMPTION" + print_stride_balance $claim_address "CLAIM" + print_stride_balance $fee_address "FEE" + + # Log staketia balance on host chain + print_separator "STAKETIA HOST" $balances + print_host_balance "$host_chain" $DELEGATION_ADDRESS "DELEGATION CONTROLLER" + print_host_balance "$host_chain" $REWARD_ADDRESS "REWARD CONTROLLER" + + # Log staketia delegations/undelegations + print_separator "STAKETIA STAKING" $balances + delegation_address=$($STRIDE_MAIN_CMD q staketia host-zone | grep "delegation_address" | awk '{print $2}') + + print_header "DELEGATIONS $host_chain" $balances + $host_cmd q staking delegations $delegation_address | grep -vE "pagination|total|next_key" >> $balances + print_header "UNBONDING-DELEGATIONS $host_chain" $balances + $host_cmd q staking unbonding-delegations $delegation_address | grep -vE "pagination|total|next_key" >> $balances + fi # Log stride channels print_separator "STRIDE" $channels @@ -184,21 +188,25 @@ while true; do print_stride_balance $community_pool_stake_address "COMMUNITY POOL STAKE HOLDING ACCT BALANCE" print_stride_balance $community_pool_redeem_address "COMMUNITY POOL REDEEM HOLDING ACCT BALANCE" + community_pool_treasury=$($STRIDE_MAIN_CMD q stakeibc show-host-zone $HOST_CHAIN_ID | grep community_pool_treasury | awk '{print $2}' | tr -d '"') + if [[ "$community_pool_treasury" != "" ]]; then + print_host_balance $chain $community_pool_treasury "COMMUNITY POOL TREASURY ADDRESS" + fi + # Log host channels print_separator "$chain" $channels $HOST_MAIN_CMD q ibc channel channels | grep -E "channel_id|port|state" >> $channels || true done - TRADE_ICA_ADDR=$($STRIDE_MAIN_CMD q stakeibc list-trade-routes | grep trade_account -A 2 | grep address | awk '{print $2}') if [[ "$TRADE_ICA_ADDR" == "$OSMO_ADDRESS_PREFIX"* ]]; then - print_header "TRADE ACCT BALANCE" >> $balances + print_header "TRADE ACCT BALANCE" $balances $OSMO_MAIN_CMD q bank balances $TRADE_ICA_ADDR >> $balances fi for chain in ${ACCESSORY_CHAINS[@]:-}; do ACCESSORY_MAIN_CMD=$(GET_VAR_VALUE ${chain}_MAIN_CMD) - print_header "========================== $chain =============================" >> $channels + print_header "========================== $chain =============================" $channels $ACCESSORY_MAIN_CMD q ibc channel channels | grep -E "channel_id|port|state" >> $channels || true done diff --git a/dockernet/src/init_chain.sh b/dockernet/src/init_chain.sh index a11210b906..44dd9def80 100644 --- a/dockernet/src/init_chain.sh +++ b/dockernet/src/init_chain.sh @@ -335,7 +335,7 @@ if [[ "$CHAIN" != "STRIDE" && "$CHAIN" != "HOST" ]]; then fi # wipe out the persistent peers for the main node (these are incorrectly autogenerated for each validator during collect-gentxs) -sed -i -E "s|persistent_peers = .*|persistent_peers = \"\"|g" $MAIN_CONFIG +sed -i -E "s|^persistent_peers = .*|persistent_peers = \"\"|g" $MAIN_CONFIG # update chain-specific genesis settings if [ "$CHAIN" == "STRIDE" ]; then diff --git a/dockernet/src/register_host.sh b/dockernet/src/register_host.sh index 6ef5f11da9..fc7252ddc4 100644 --- a/dockernet/src/register_host.sh +++ b/dockernet/src/register_host.sh @@ -23,9 +23,14 @@ if [[ "$CHAIN" == "GAIA" ]]; then LSM_ENABLED="true" fi +COMMUNITY_POOL_TREASURY_ADDRESS="" +if [[ "$CHAIN" == "DYDX" ]]; then + COMMUNITY_POOL_TREASURY_ADDRESS="--community-pool-treasury-address dydx15ztc7xy42tn2ukkc0qjthkucw9ac63pgp70urn" +fi + echo "$CHAIN - Registering host zone..." $STRIDE_MAIN_CMD tx stakeibc register-host-zone \ - $CONNECTION $HOST_DENOM $ADDRESS_PREFIX $IBC_DENOM $CHANNEL 1 $LSM_ENABLED \ + $CONNECTION $HOST_DENOM $ADDRESS_PREFIX $IBC_DENOM $CHANNEL 1 $LSM_ENABLED $COMMUNITY_POOL_TREASURY_ADDRESS \ --gas 1000000 --from $STRIDE_ADMIN_ACCT --home $DOCKERNET_HOME/state/stride1 -y | TRIM_TX sleep 10 diff --git a/dockernet/start_network.sh b/dockernet/start_network.sh index 831b5137ec..9cd6c36093 100755 --- a/dockernet/start_network.sh +++ b/dockernet/start_network.sh @@ -57,6 +57,8 @@ done # Start each chain, create the transfer channels and start the relayers +# For dydx, sleep before and after the relayers are setup to get it some time to startup +# since it's a computationally expensive chain bash $SRC/start_chain.sh bash $SRC/start_relayers.sh diff --git a/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance.go b/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance.go index 0fdbf05e04..fb66c69078 100644 --- a/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance.go +++ b/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance.go @@ -67,7 +67,7 @@ func WithdrawalRewardBalanceCallback(k Keeper, ctx sdk.Context, args []byte, que // If there's a rebate portion, fund the community pool with that amount if rebateAmount.GT(sdkmath.ZeroInt()) { - rebateToken := sdk.NewCoin(tradeRouteCallback.RewardDenom, rebateAmount) + rebateToken := sdk.NewCoin(tradeRoute.RewardDenomOnHostZone, rebateAmount) if err := k.FundCommunityPool(ctx, hostZone, rebateToken, types.ICAAccountType_WITHDRAWAL); err != nil { return errorsmod.Wrapf(err, "unable to submit fund community pool ICA") } diff --git a/x/stakeibc/keeper/reward_converter.go b/x/stakeibc/keeper/reward_converter.go index 78b1a8418a..554278dbdb 100644 --- a/x/stakeibc/keeper/reward_converter.go +++ b/x/stakeibc/keeper/reward_converter.go @@ -197,7 +197,9 @@ func (k Keeper) BuildTradeAuthzMsg( switch permissionChange { case types.AuthzPermissionChange_GRANT: authorization := authz.NewGenericAuthorization(swapMsgTypeUrl) - grant, err := authz.NewGrant(ctx.BlockTime(), authorization, nil) + expiration := ctx.BlockTime().Add(time.Hour * 24 * 365 * 100) // 100 years + + grant, err := authz.NewGrant(ctx.BlockTime(), authorization, &expiration) if err != nil { return nil, errorsmod.Wrapf(err, "unable to build grant struct") } @@ -206,12 +208,14 @@ func (k Keeper) BuildTradeAuthzMsg( Grantee: grantee, Grant: grant, }} + case types.AuthzPermissionChange_REVOKE: authzMsg = []proto.Message{&authz.MsgRevoke{ Granter: tradeRoute.TradeAccount.Address, Grantee: grantee, MsgTypeUrl: swapMsgTypeUrl, }} + default: return nil, errors.New("invalid permission change") } @@ -296,12 +300,6 @@ func (k Keeper) TransferRewardTokensHostToTrade(ctx sdk.Context, amount sdkmath. return nil } - // Similarly, if there's no price on the trade route yet, don't initiate the transfer because - // we know the swap will not be submitted - if route.TradeConfig.SwapPrice.IsZero() { - return nil - } - // Build the PFM transfer message from host to trade zone msg, err := k.BuildHostToTradeTransferMsg(ctx, amount, route) if err != nil { From 609e0d29819e0704708339ff5c6c7bf158d844c1 Mon Sep 17 00:00:00 2001 From: riley-stride <104941670+riley-stride@users.noreply.github.com> Date: Thu, 21 Mar 2024 00:50:09 -0400 Subject: [PATCH 11/13] v20 host zone migration (add community pool treasury) (#1154) Co-authored-by: sampocs --- app/upgrades/v20/upgrades.go | 21 +++++++++++++++------ app/upgrades/v20/upgrades_test.go | 17 +++++++++++++++++ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/app/upgrades/v20/upgrades.go b/app/upgrades/v20/upgrades.go index f69477c013..cda897c4c9 100644 --- a/app/upgrades/v20/upgrades.go +++ b/app/upgrades/v20/upgrades.go @@ -9,12 +9,13 @@ import ( ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" stakeibckeeper "github.com/Stride-Labs/stride/v19/x/stakeibc/keeper" + stakeibctypes "github.com/Stride-Labs/stride/v19/x/stakeibc/types" ) const ( - UpgradeName = "v20" - dydxCPTreasuryAddress = "dydx15ztc7xy42tn2ukkc0qjthkucw9ac63pgp70urn" - dydxChainId = "dydx-mainnet-1" + UpgradeName = "v20" + DydxCommunityPoolTreasuryAddress = "dydx15ztc7xy42tn2ukkc0qjthkucw9ac63pgp70urn" + DydxChainId = "dydx-mainnet-1" ) // CreateUpgradeHandler creates an SDK upgrade handler for v20 @@ -22,7 +23,7 @@ func CreateUpgradeHandler( mm *module.Manager, configurator module.Configurator, consumerKeeper ccvconsumerkeeper.Keeper, - stakeIbcKeeper stakeibckeeper.Keeper, + stakeibcKeeper stakeibckeeper.Keeper, ) upgradetypes.UpgradeHandler { return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { ctx.Logger().Info("Starting upgrade v20...") @@ -42,19 +43,27 @@ func CreateUpgradeHandler( MigrateICSParams(ctx, consumerKeeper) ctx.Logger().Info("Adding DYDX Community Pool Treasury Address...") + if err := SetDydxCommunityPoolTreasuryAddress(ctx, stakeibcKeeper); err != nil { + return newVm, err + } return newVm, nil } } // Write the Community Pool Treasury Address to the DYDX host_zone struct -func SetDydxCommunityPoolTreasuryAddress(ctx sdk.Context, stakeIbcKeeper stakeibckeeper.Keeper) error { - +func SetDydxCommunityPoolTreasuryAddress(ctx sdk.Context, k stakeibckeeper.Keeper) error { // Get the dydx host_zone + hostZone, found := k.GetHostZone(ctx, DydxChainId) + if !found { + return stakeibctypes.ErrHostZoneNotFound.Wrapf("dydx host zone not found") + } // Set the treasury address + hostZone.CommunityPoolTreasuryAddress = DydxCommunityPoolTreasuryAddress // Save the dydx host_zone + k.SetHostZone(ctx, hostZone) return nil } diff --git a/app/upgrades/v20/upgrades_test.go b/app/upgrades/v20/upgrades_test.go index bedaf5e8d3..00a57898e9 100644 --- a/app/upgrades/v20/upgrades_test.go +++ b/app/upgrades/v20/upgrades_test.go @@ -6,6 +6,8 @@ import ( "github.com/stretchr/testify/suite" "github.com/Stride-Labs/stride/v19/app/apptesting" + v20 "github.com/Stride-Labs/stride/v19/app/upgrades/v20" + stakeibctypes "github.com/Stride-Labs/stride/v19/x/stakeibc/types" ) type UpgradeTestSuite struct { @@ -21,4 +23,19 @@ func TestKeeperTestSuite(t *testing.T) { } func (s *UpgradeTestSuite) TestUpgrade() { + dummyUpgradeHeight := int64(5) + + // Create a dydx host zone + s.App.StakeibcKeeper.SetHostZone(s.Ctx, stakeibctypes.HostZone{ + ChainId: v20.DydxChainId, + }) + + // Run the upgrade + s.ConfirmUpgradeSucceededs("v20", dummyUpgradeHeight) + + // Confirm the treasury address was added to dydx + hostZone, found := s.App.StakeibcKeeper.GetHostZone(s.Ctx, v20.DydxChainId) + s.Require().True(found, "host zone should have been found") + s.Require().Equal(v20.DydxCommunityPoolTreasuryAddress, hostZone.CommunityPoolTreasuryAddress, + "community pool treasury address") } From be7386b82b78572a22e9971a1d39b42422b2f28b Mon Sep 17 00:00:00 2001 From: sampocs Date: Wed, 20 Mar 2024 23:54:05 -0500 Subject: [PATCH 12/13] fixed typo --- app/apptesting/test_helpers.go | 2 +- .../keeper/icqcallbacks_withdrawal_reward_balance_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/apptesting/test_helpers.go b/app/apptesting/test_helpers.go index 21a1efd175..ce7e233eba 100644 --- a/app/apptesting/test_helpers.go +++ b/app/apptesting/test_helpers.go @@ -413,7 +413,7 @@ func (s *AppTestHelper) CheckICATxNotSubmitted(portId, channelId string, icaFunc // Helper function to check if multiple ICA txs were submitted by seeing if the sequence number // incremented by more than 1 -func (s *AppTestHelper) CheckMulitpleICATxSubmitted(portId, channelId string, icaFunction func() error) { +func (s *AppTestHelper) CheckMultipleICATxSubmitted(portId, channelId string, icaFunction func() error) { // Get the sequence before the tested funciton is run startSequence := s.MustGetNextSequenceNumber(portId, channelId) diff --git a/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance_test.go b/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance_test.go index d9d1d2ad40..4640c8794e 100644 --- a/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance_test.go +++ b/x/stakeibc/keeper/icqcallbacks_withdrawal_reward_balance_test.go @@ -129,7 +129,7 @@ func (s *KeeperTestSuite) TestWithdrawalRewardBalanceCallback_SuccessfulWithReba s.FundAccount(s.TestAccs[0], sdk.NewCoin(types.StAssetDenomFromHostZoneDenom(hostZone.HostDenom), stTokenSupply)) // ICA inside of TransferRewardTokensHostToTrade should not actually execute because of min_swap_amount - s.CheckMulitpleICATxSubmitted(tc.PortID, tc.ChannelID, func() error { + s.CheckMultipleICATxSubmitted(tc.PortID, tc.ChannelID, func() error { return keeper.WithdrawalRewardBalanceCallback(s.App.StakeibcKeeper, s.Ctx, tc.Response.CallbackArgs, tc.Response.Query) }) } From 6dfda112cd551b292bc7f5521d9d4bb52e5496e9 Mon Sep 17 00:00:00 2001 From: sampocs Date: Thu, 21 Mar 2024 00:02:03 -0500 Subject: [PATCH 13/13] fixed unit tests --- x/stakeibc/keeper/reward_converter_test.go | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/x/stakeibc/keeper/reward_converter_test.go b/x/stakeibc/keeper/reward_converter_test.go index 5b5e066760..0bf2709343 100644 --- a/x/stakeibc/keeper/reward_converter_test.go +++ b/x/stakeibc/keeper/reward_converter_test.go @@ -605,9 +605,10 @@ func (s *KeeperTestSuite) TestBuildTradeAuthzMsg() { s.Require().Equal(granteeAddress, grantMsg.Grantee, "grantee of grant message") authorization, err := grantMsg.Grant.GetAuthorization() + expectedExpiration := s.Ctx.BlockTime().Add(time.Hour * 24 * 365 * 100) s.Require().NoError(err) s.Require().Equal(expectedTypeUrl, authorization.MsgTypeURL(), "grant msg type url") - s.Require().Nil(grantMsg.Grant.Expiration, "expiration should be nil") + s.Require().Equal(expectedExpiration, *grantMsg.Grant.Expiration, "expiration should be one year from the current block time") // Test revoking trade permissions msgs, err = s.App.StakeibcKeeper.BuildTradeAuthzMsg(s.Ctx, tradeRoute, types.AuthzPermissionChange_REVOKE, granteeAddress) @@ -767,19 +768,6 @@ func (s *KeeperTestSuite) TestTransferRewardTokensHostToTrade_TransferAmountBelo }) } -func (s *KeeperTestSuite) TestTransferRewardTokensHostToTrade_NoPoolPrice() { - tc := s.SetupTransferRewardTokensHostToTradeTestCase() - - // Attempt to call the function with a route that does not have a pool price - // If should not initiate the transfer (since the swap would be unable to execute) - invalidRoute := tc.TradeRoute - invalidRoute.TradeConfig.SwapPrice = sdk.ZeroDec() - - s.CheckICATxNotSubmitted(tc.PortID, tc.ChannelID, func() error { - return s.App.StakeibcKeeper.TransferRewardTokensHostToTrade(s.Ctx, tc.TransferAmount, invalidRoute) - }) -} - func (s *KeeperTestSuite) TestTransferRewardTokensHostToTrade_FailedToSubmitICA() { tc := s.SetupTransferRewardTokensHostToTradeTestCase()