diff --git a/docs/core/proto-docs.md b/docs/core/proto-docs.md index 25798639..25b98d4c 100644 --- a/docs/core/proto-docs.md +++ b/docs/core/proto-docs.md @@ -178,6 +178,10 @@ - [Msg](#kava.committee.v1beta1.Msg) +- [kava/community/v1beta1/proposal.proto](#kava/community/v1beta1/proposal.proto) + - [CommunityPoolLendDepositProposal](#kava.community.v1beta1.CommunityPoolLendDepositProposal) + - [CommunityPoolLendWithdrawProposal](#kava.community.v1beta1.CommunityPoolLendWithdrawProposal) + - [kava/community/v1beta1/query.proto](#kava/community/v1beta1/query.proto) - [QueryBalanceRequest](#kava.community.v1beta1.QueryBalanceRequest) - [QueryBalanceResponse](#kava.community.v1beta1.QueryBalanceResponse) @@ -2838,6 +2842,56 @@ Msg defines the committee Msg service + +

Top

+ +## kava/community/v1beta1/proposal.proto + + + + + +### CommunityPoolLendDepositProposal +CommunityPoolLendDepositProposal deposits from the community pool into lend + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `title` | [string](#string) | | | +| `description` | [string](#string) | | | +| `amount` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | | + + + + + + + + +### CommunityPoolLendWithdrawProposal +CommunityPoolLendWithdrawProposal withdraws a lend position back to the community pool + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `title` | [string](#string) | | | +| `description` | [string](#string) | | | +| `amount` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | | + + + + + + + + + + + + + + +

Top

diff --git a/proto/kava/community/v1beta1/proposal.proto b/proto/kava/community/v1beta1/proposal.proto new file mode 100644 index 00000000..e1e899ea --- /dev/null +++ b/proto/kava/community/v1beta1/proposal.proto @@ -0,0 +1,33 @@ +syntax = "proto3"; +package kava.community.v1beta1; + +import "cosmos/base/v1beta1/coin.proto"; +import "gogoproto/gogo.proto"; + +option go_package = "github.com/kava-labs/kava/x/community/types"; + +// CommunityPoolLendDepositProposal deposits from the community pool into lend +message CommunityPoolLendDepositProposal { + option (gogoproto.goproto_stringer) = false; + option (gogoproto.goproto_getters) = false; + + string title = 1; + string description = 2; + repeated cosmos.base.v1beta1.Coin amount = 3 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + +// CommunityPoolLendWithdrawProposal withdraws a lend position back to the community pool +message CommunityPoolLendWithdrawProposal { + option (gogoproto.goproto_stringer) = false; + option (gogoproto.goproto_getters) = false; + + string title = 1; + string description = 2; + repeated cosmos.base.v1beta1.Coin amount = 3 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} diff --git a/x/community/types/proposal.go b/x/community/types/proposal.go new file mode 100644 index 00000000..51448ac4 --- /dev/null +++ b/x/community/types/proposal.go @@ -0,0 +1,122 @@ +package types + +import ( + fmt "fmt" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" +) + +const ( + // ProposalTypeCommunityPoolLendDeposit defines the type for a CommunityPoolLendDepositProposal + ProposalTypeCommunityPoolLendDeposit = "CommunityPoolLendDeposit" + // ProposalTypeCommunityPoolLendWithdraw defines the type for a CommunityPoolLendDepositProposal + ProposalTypeCommunityPoolLendWithdraw = "CommunityPoolLendWithdraw" +) + +// Assert CommunityPoolLendDepositProposal implements govtypes.Content at compile-time +var ( + _ govtypes.Content = &CommunityPoolLendDepositProposal{} + _ govtypes.Content = &CommunityPoolLendWithdrawProposal{} +) + +func init() { + govtypes.RegisterProposalType(ProposalTypeCommunityPoolLendDeposit) + govtypes.RegisterProposalTypeCodec(&CommunityPoolLendDepositProposal{}, "kava/CommunityPoolLendDepositProposal") + govtypes.RegisterProposalType(ProposalTypeCommunityPoolLendWithdraw) + govtypes.RegisterProposalTypeCodec(&CommunityPoolLendWithdrawProposal{}, "kava/CommunityPoolLendWithdrawProposal") +} + +// NewCommunityPoolLendDepositProposal creates a new community pool deposit proposal. +func NewCommunityPoolLendDepositProposal(title, description string, amount sdk.Coins) *CommunityPoolLendDepositProposal { + return &CommunityPoolLendDepositProposal{ + Title: title, + Description: description, + Amount: amount, + } +} + +// GetTitle returns the title of a community pool lend deposit proposal. +func (p *CommunityPoolLendDepositProposal) GetTitle() string { return p.Title } + +// GetDescription returns the description of a community pool lend deposit proposal. +func (p *CommunityPoolLendDepositProposal) GetDescription() string { return p.Description } + +// GetDescription returns the routing key of a community pool lend deposit proposal. +func (p *CommunityPoolLendDepositProposal) ProposalRoute() string { return ModuleName } + +// ProposalType returns the type of a community pool lend deposit proposal. +func (p *CommunityPoolLendDepositProposal) ProposalType() string { + return ProposalTypeCommunityPoolLendDeposit +} + +// String implements fmt.Stringer +func (p *CommunityPoolLendDepositProposal) String() string { + var b strings.Builder + b.WriteString(fmt.Sprintf(`Community Pool Lend Deposit Proposal: + Title: %s + Description: %s + Amount: %s +`, p.Title, p.Description, p.Amount)) + return b.String() +} + +// ValidateBasic stateless validation of a community pool lend deposit proposal. +func (p *CommunityPoolLendDepositProposal) ValidateBasic() error { + if err := govtypes.ValidateAbstract(p); err != nil { + return err + } + // ensure the proposal has valid amount + if !p.Amount.IsValid() || p.Amount.IsZero() { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "deposit amount %s", p.Amount) + } + return p.Amount.Validate() +} + +// NewCommunityPoolLendWithdrawProposal creates a new community pool lend withdraw proposal. +func NewCommunityPoolLendWithdrawProposal(title, description string, amount sdk.Coins) *CommunityPoolLendWithdrawProposal { + return &CommunityPoolLendWithdrawProposal{ + Title: title, + Description: description, + Amount: amount, + } +} + +// GetTitle returns the title of a community pool withdraw proposal. +func (p *CommunityPoolLendWithdrawProposal) GetTitle() string { return p.Title } + +// GetDescription returns the description of a community pool withdraw proposal. +func (p *CommunityPoolLendWithdrawProposal) GetDescription() string { return p.Description } + +// GetDescription returns the routing key of a community pool withdraw proposal. +func (p *CommunityPoolLendWithdrawProposal) ProposalRoute() string { return ModuleName } + +// ProposalType returns the type of a community pool withdraw proposal. +func (p *CommunityPoolLendWithdrawProposal) ProposalType() string { + return ProposalTypeCommunityPoolLendWithdraw +} + +// String implements fmt.Stringer +func (p *CommunityPoolLendWithdrawProposal) String() string { + var b strings.Builder + b.WriteString(fmt.Sprintf(`Community Pool Lend Withdraw Proposal: + Title: %s + Description: %s + Amount: %s +`, p.Title, p.Description, p.Amount)) + return b.String() +} + +// ValidateBasic stateless validation of a community pool withdraw proposal. +func (p *CommunityPoolLendWithdrawProposal) ValidateBasic() error { + if err := govtypes.ValidateAbstract(p); err != nil { + return err + } + // ensure the proposal has valid amount + if !p.Amount.IsValid() || p.Amount.IsZero() { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "withdraw amount %s", p.Amount) + } + return p.Amount.Validate() +} diff --git a/x/community/types/proposal.pb.go b/x/community/types/proposal.pb.go new file mode 100644 index 00000000..2c0e515e --- /dev/null +++ b/x/community/types/proposal.pb.go @@ -0,0 +1,684 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: kava/community/v1beta1/proposal.proto + +package types + +import ( + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// CommunityPoolLendDepositProposal deposits from the community pool into lend +type CommunityPoolLendDepositProposal struct { + Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Amount github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,3,rep,name=amount,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amount"` +} + +func (m *CommunityPoolLendDepositProposal) Reset() { *m = CommunityPoolLendDepositProposal{} } +func (*CommunityPoolLendDepositProposal) ProtoMessage() {} +func (*CommunityPoolLendDepositProposal) Descriptor() ([]byte, []int) { + return fileDescriptor_64aa83b2ed448ec1, []int{0} +} +func (m *CommunityPoolLendDepositProposal) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CommunityPoolLendDepositProposal) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CommunityPoolLendDepositProposal.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 *CommunityPoolLendDepositProposal) XXX_Merge(src proto.Message) { + xxx_messageInfo_CommunityPoolLendDepositProposal.Merge(m, src) +} +func (m *CommunityPoolLendDepositProposal) XXX_Size() int { + return m.Size() +} +func (m *CommunityPoolLendDepositProposal) XXX_DiscardUnknown() { + xxx_messageInfo_CommunityPoolLendDepositProposal.DiscardUnknown(m) +} + +var xxx_messageInfo_CommunityPoolLendDepositProposal proto.InternalMessageInfo + +// CommunityPoolLendWithdrawProposal withdraws a lend position back to the community pool +type CommunityPoolLendWithdrawProposal struct { + Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Amount github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,3,rep,name=amount,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amount"` +} + +func (m *CommunityPoolLendWithdrawProposal) Reset() { *m = CommunityPoolLendWithdrawProposal{} } +func (*CommunityPoolLendWithdrawProposal) ProtoMessage() {} +func (*CommunityPoolLendWithdrawProposal) Descriptor() ([]byte, []int) { + return fileDescriptor_64aa83b2ed448ec1, []int{1} +} +func (m *CommunityPoolLendWithdrawProposal) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CommunityPoolLendWithdrawProposal) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CommunityPoolLendWithdrawProposal.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 *CommunityPoolLendWithdrawProposal) XXX_Merge(src proto.Message) { + xxx_messageInfo_CommunityPoolLendWithdrawProposal.Merge(m, src) +} +func (m *CommunityPoolLendWithdrawProposal) XXX_Size() int { + return m.Size() +} +func (m *CommunityPoolLendWithdrawProposal) XXX_DiscardUnknown() { + xxx_messageInfo_CommunityPoolLendWithdrawProposal.DiscardUnknown(m) +} + +var xxx_messageInfo_CommunityPoolLendWithdrawProposal proto.InternalMessageInfo + +func init() { + proto.RegisterType((*CommunityPoolLendDepositProposal)(nil), "kava.community.v1beta1.CommunityPoolLendDepositProposal") + proto.RegisterType((*CommunityPoolLendWithdrawProposal)(nil), "kava.community.v1beta1.CommunityPoolLendWithdrawProposal") +} + +func init() { + proto.RegisterFile("kava/community/v1beta1/proposal.proto", fileDescriptor_64aa83b2ed448ec1) +} + +var fileDescriptor_64aa83b2ed448ec1 = []byte{ + // 325 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0xcd, 0x4e, 0x2c, 0x4b, + 0xd4, 0x4f, 0xce, 0xcf, 0xcd, 0x2d, 0xcd, 0xcb, 0x2c, 0xa9, 0xd4, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, + 0x49, 0x34, 0xd4, 0x2f, 0x28, 0xca, 0x2f, 0xc8, 0x2f, 0x4e, 0xcc, 0xd1, 0x2b, 0x28, 0xca, 0x2f, + 0xc9, 0x17, 0x12, 0x03, 0x29, 0xd3, 0x83, 0x2b, 0xd3, 0x83, 0x2a, 0x93, 0x92, 0x4b, 0xce, 0x2f, + 0xce, 0xcd, 0x2f, 0xd6, 0x4f, 0x4a, 0x2c, 0x4e, 0x85, 0xeb, 0x4d, 0xce, 0xcf, 0xcc, 0x83, 0xe8, + 0x93, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x33, 0xf5, 0x41, 0x2c, 0x88, 0xa8, 0xd2, 0x49, 0x46, + 0x2e, 0x05, 0x67, 0x98, 0x59, 0x01, 0xf9, 0xf9, 0x39, 0x3e, 0xa9, 0x79, 0x29, 0x2e, 0xa9, 0x05, + 0xf9, 0xc5, 0x99, 0x25, 0x01, 0x50, 0x8b, 0x85, 0x44, 0xb8, 0x58, 0x4b, 0x32, 0x4b, 0x72, 0x52, + 0x25, 0x18, 0x15, 0x18, 0x35, 0x38, 0x83, 0x20, 0x1c, 0x21, 0x05, 0x2e, 0xee, 0x94, 0xd4, 0xe2, + 0xe4, 0xa2, 0xcc, 0x82, 0x92, 0xcc, 0xfc, 0x3c, 0x09, 0x26, 0xb0, 0x1c, 0xb2, 0x90, 0x50, 0x32, + 0x17, 0x5b, 0x62, 0x6e, 0x7e, 0x69, 0x5e, 0x89, 0x04, 0xb3, 0x02, 0xb3, 0x06, 0xb7, 0x91, 0xa4, + 0x1e, 0xc4, 0x8d, 0x7a, 0x20, 0x37, 0xc2, 0x1c, 0xae, 0xe7, 0x9c, 0x9f, 0x99, 0xe7, 0x64, 0x70, + 0xe2, 0x9e, 0x3c, 0xc3, 0xaa, 0xfb, 0xf2, 0x1a, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x20, 0xff, + 0xe9, 0x43, 0x3d, 0x04, 0xa1, 0x74, 0x8b, 0x53, 0xb2, 0xf5, 0x4b, 0x2a, 0x0b, 0x52, 0x8b, 0xc1, + 0x1a, 0x8a, 0x83, 0xa0, 0x46, 0x5b, 0x71, 0x74, 0x2c, 0x90, 0x67, 0x98, 0xb1, 0x40, 0x9e, 0x41, + 0xe9, 0x14, 0x23, 0x97, 0x22, 0x86, 0x5f, 0xc2, 0x33, 0x4b, 0x32, 0x52, 0x8a, 0x12, 0xcb, 0x87, + 0x98, 0x67, 0x9c, 0x5c, 0x4f, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, + 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x4a, 0x1b, + 0xc9, 0x54, 0x50, 0x5a, 0xd0, 0xcd, 0x49, 0x4c, 0x2a, 0x06, 0xb3, 0xf4, 0x2b, 0x90, 0x92, 0x0f, + 0xd8, 0xf8, 0x24, 0x36, 0x70, 0x34, 0x1b, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xa0, 0x07, 0x87, + 0x4d, 0x5d, 0x02, 0x00, 0x00, +} + +func (m *CommunityPoolLendDepositProposal) 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 *CommunityPoolLendDepositProposal) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CommunityPoolLendDepositProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Amount) > 0 { + for iNdEx := len(m.Amount) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Amount[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintProposal(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintProposal(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x12 + } + if len(m.Title) > 0 { + i -= len(m.Title) + copy(dAtA[i:], m.Title) + i = encodeVarintProposal(dAtA, i, uint64(len(m.Title))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *CommunityPoolLendWithdrawProposal) 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 *CommunityPoolLendWithdrawProposal) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CommunityPoolLendWithdrawProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Amount) > 0 { + for iNdEx := len(m.Amount) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Amount[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintProposal(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintProposal(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x12 + } + if len(m.Title) > 0 { + i -= len(m.Title) + copy(dAtA[i:], m.Title) + i = encodeVarintProposal(dAtA, i, uint64(len(m.Title))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintProposal(dAtA []byte, offset int, v uint64) int { + offset -= sovProposal(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *CommunityPoolLendDepositProposal) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Title) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + if len(m.Amount) > 0 { + for _, e := range m.Amount { + l = e.Size() + n += 1 + l + sovProposal(uint64(l)) + } + } + return n +} + +func (m *CommunityPoolLendWithdrawProposal) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Title) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + if len(m.Amount) > 0 { + for _, e := range m.Amount { + l = e.Size() + n += 1 + l + sovProposal(uint64(l)) + } + } + return n +} + +func sovProposal(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozProposal(x uint64) (n int) { + return sovProposal(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *CommunityPoolLendDepositProposal) 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 ErrIntOverflowProposal + } + 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: CommunityPoolLendDepositProposal: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CommunityPoolLendDepositProposal: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Title", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + 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 ErrInvalidLengthProposal + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Title = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + 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 ErrInvalidLengthProposal + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Amount = append(m.Amount, types.Coin{}) + if err := m.Amount[len(m.Amount)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipProposal(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthProposal + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CommunityPoolLendWithdrawProposal) 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 ErrIntOverflowProposal + } + 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: CommunityPoolLendWithdrawProposal: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CommunityPoolLendWithdrawProposal: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Title", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + 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 ErrInvalidLengthProposal + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Title = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + 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 ErrInvalidLengthProposal + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Amount = append(m.Amount, types.Coin{}) + if err := m.Amount[len(m.Amount)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipProposal(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthProposal + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipProposal(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowProposal + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowProposal + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowProposal + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthProposal + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupProposal + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthProposal + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthProposal = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowProposal = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupProposal = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/community/types/proposal_test.go b/x/community/types/proposal_test.go new file mode 100644 index 00000000..abf7bf89 --- /dev/null +++ b/x/community/types/proposal_test.go @@ -0,0 +1,136 @@ +package types_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + + "github.com/kava-labs/kava/x/community/types" +) + +func TestLendProposals_ValidateBasic(t *testing.T) { + // each proposalData is tested with Deposit and Withdraw proposals + type proposalData struct { + Title string + Description string + Amount sdk.Coins + } + testCases := []struct { + name string + proposal proposalData + expectedErr string + }{ + { + name: "valid proposal", + proposal: proposalData{ + Title: "I'm a lend proposal", + Description: "I interact with lend", + Amount: sdk.NewCoins(sdk.NewInt64Coin("ukava", 1e10)), + }, + expectedErr: "", + }, + { + name: "invalid - fails gov validation", + proposal: proposalData{ + Description: "I have no title.", + }, + expectedErr: "invalid proposal content", + }, + { + name: "invalid - nil coins", + proposal: proposalData{ + Title: "Error profoundly", + Description: "My coins are nil", + Amount: nil, + }, + expectedErr: "invalid coins", + }, + { + name: "invalid - empty coins", + proposal: proposalData{ + Title: "Error profoundly", + Description: "My coins are empty", + Amount: sdk.NewCoins(), + }, + expectedErr: "invalid coins", + }, + { + name: "invalid - zero coins", + proposal: proposalData{ + Title: "Error profoundly", + Description: "My coins are zero", + Amount: sdk.NewCoins(sdk.NewCoin("ukava", sdk.ZeroInt())), + }, + expectedErr: "invalid coins", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + t.Run("CommunityPoolLendDepositProposal", func(t *testing.T) { + deposit := types.NewCommunityPoolLendDepositProposal( + tc.proposal.Title, + tc.proposal.Description, + tc.proposal.Amount, + ) + err := deposit.ValidateBasic() + if tc.expectedErr != "" { + require.ErrorContains(t, err, tc.expectedErr) + return + } + + require.NoError(t, err) + require.Equal(t, deposit.Title, deposit.GetTitle()) + require.Equal(t, deposit.Description, deposit.GetDescription()) + require.Equal(t, types.ModuleName, deposit.ProposalRoute()) + require.Equal(t, types.ProposalTypeCommunityPoolLendDeposit, deposit.ProposalType()) + }) + + t.Run("CommunityPoolLendWithdrawProposal", func(t *testing.T) { + withdrawl := types.NewCommunityPoolLendWithdrawProposal( + tc.proposal.Title, + tc.proposal.Description, + tc.proposal.Amount, + ) + err := withdrawl.ValidateBasic() + if tc.expectedErr != "" { + require.ErrorContains(t, err, tc.expectedErr) + return + } + + require.NoError(t, err) + require.Equal(t, withdrawl.Title, withdrawl.GetTitle()) + require.Equal(t, withdrawl.Description, withdrawl.GetDescription()) + require.Equal(t, types.ModuleName, withdrawl.ProposalRoute()) + require.Equal(t, types.ProposalTypeCommunityPoolLendWithdraw, withdrawl.ProposalType()) + }) + }) + } +} + +func TestCommunityPoolLendDepositProposal_Stringer(t *testing.T) { + proposal := types.NewCommunityPoolLendDepositProposal( + "Title", + "Description", + sdk.NewCoins(sdk.NewInt64Coin("ukava", 42)), + ) + require.Equal(t, `Community Pool Lend Deposit Proposal: + Title: Title + Description: Description + Amount: 42ukava +`, proposal.String()) +} + +func TestCommunityPoolLendWithdrawProposal_Stringer(t *testing.T) { + proposal := types.NewCommunityPoolLendWithdrawProposal( + "Title", + "Description", + sdk.NewCoins(sdk.NewInt64Coin("ukava", 42)), + ) + require.Equal(t, `Community Pool Lend Withdraw Proposal: + Title: Title + Description: Description + Amount: 42ukava +`, proposal.String()) +}