diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fd88b1a..9cf07a3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,8 @@ Contains all the PRs that improved the code without changing the behaviors. - Thorchain Claims Proto Updates - Documentation of Testnet Setup using local build and Cosmovisor - Documentation update and addition of validator setup documentation +- New Module accounts to handle rewards +- New Params to Arkeo Module ## Fixed - Testnet binary generation using go build @@ -46,6 +48,7 @@ Contains all the PRs that improved the code without changing the behaviors. - claim timeout - Fixed module imports - update module to implement APPModuleBasic and AppModule +- Updated Tests on arkeo module keeper # v1.0.0-Prerelease diff --git a/api/arkeo/arkeo/params.pulsar.go b/api/arkeo/arkeo/params.pulsar.go index ea521687..1a3b1573 100644 --- a/api/arkeo/arkeo/params.pulsar.go +++ b/api/arkeo/arkeo/params.pulsar.go @@ -2,7 +2,9 @@ package arkeo import ( + _ "cosmossdk.io/api/cosmos/base/v1beta1" fmt "fmt" + _ "github.com/cosmos/cosmos-proto" runtime "github.com/cosmos/cosmos-proto/runtime" _ "github.com/cosmos/gogoproto/gogoproto" protoreflect "google.golang.org/protobuf/reflect/protoreflect" @@ -14,12 +16,18 @@ import ( ) var ( - md_Params protoreflect.MessageDescriptor + md_Params protoreflect.MessageDescriptor + fd_Params_CommunityPoolPercentage protoreflect.FieldDescriptor + fd_Params_DevFundPercentage protoreflect.FieldDescriptor + fd_Params_ValidatorRewardsPercentage protoreflect.FieldDescriptor ) func init() { file_arkeo_arkeo_params_proto_init() md_Params = File_arkeo_arkeo_params_proto.Messages().ByName("Params") + fd_Params_CommunityPoolPercentage = md_Params.Fields().ByName("CommunityPoolPercentage") + fd_Params_DevFundPercentage = md_Params.Fields().ByName("DevFundPercentage") + fd_Params_ValidatorRewardsPercentage = md_Params.Fields().ByName("ValidatorRewardsPercentage") } var _ protoreflect.Message = (*fastReflection_Params)(nil) @@ -87,6 +95,24 @@ func (x *fastReflection_Params) Interface() protoreflect.ProtoMessage { // While iterating, mutating operations may only be performed // on the current field descriptor. func (x *fastReflection_Params) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.CommunityPoolPercentage != "" { + value := protoreflect.ValueOfString(x.CommunityPoolPercentage) + if !f(fd_Params_CommunityPoolPercentage, value) { + return + } + } + if x.DevFundPercentage != "" { + value := protoreflect.ValueOfString(x.DevFundPercentage) + if !f(fd_Params_DevFundPercentage, value) { + return + } + } + if x.ValidatorRewardsPercentage != "" { + value := protoreflect.ValueOfString(x.ValidatorRewardsPercentage) + if !f(fd_Params_ValidatorRewardsPercentage, value) { + return + } + } } // Has reports whether a field is populated. @@ -102,6 +128,12 @@ func (x *fastReflection_Params) Range(f func(protoreflect.FieldDescriptor, proto // a repeated field is populated if it is non-empty. func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { + case "arkeo.arkeo.Params.CommunityPoolPercentage": + return x.CommunityPoolPercentage != "" + case "arkeo.arkeo.Params.DevFundPercentage": + return x.DevFundPercentage != "" + case "arkeo.arkeo.Params.ValidatorRewardsPercentage": + return x.ValidatorRewardsPercentage != "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: arkeo.arkeo.Params")) @@ -118,6 +150,12 @@ func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { + case "arkeo.arkeo.Params.CommunityPoolPercentage": + x.CommunityPoolPercentage = "" + case "arkeo.arkeo.Params.DevFundPercentage": + x.DevFundPercentage = "" + case "arkeo.arkeo.Params.ValidatorRewardsPercentage": + x.ValidatorRewardsPercentage = "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: arkeo.arkeo.Params")) @@ -134,6 +172,15 @@ func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { + case "arkeo.arkeo.Params.CommunityPoolPercentage": + value := x.CommunityPoolPercentage + return protoreflect.ValueOfString(value) + case "arkeo.arkeo.Params.DevFundPercentage": + value := x.DevFundPercentage + return protoreflect.ValueOfString(value) + case "arkeo.arkeo.Params.ValidatorRewardsPercentage": + value := x.ValidatorRewardsPercentage + return protoreflect.ValueOfString(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: arkeo.arkeo.Params")) @@ -154,6 +201,12 @@ func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) pro // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { + case "arkeo.arkeo.Params.CommunityPoolPercentage": + x.CommunityPoolPercentage = value.Interface().(string) + case "arkeo.arkeo.Params.DevFundPercentage": + x.DevFundPercentage = value.Interface().(string) + case "arkeo.arkeo.Params.ValidatorRewardsPercentage": + x.ValidatorRewardsPercentage = value.Interface().(string) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: arkeo.arkeo.Params")) @@ -174,6 +227,12 @@ func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value proto // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { + case "arkeo.arkeo.Params.CommunityPoolPercentage": + panic(fmt.Errorf("field CommunityPoolPercentage of message arkeo.arkeo.Params is not mutable")) + case "arkeo.arkeo.Params.DevFundPercentage": + panic(fmt.Errorf("field DevFundPercentage of message arkeo.arkeo.Params is not mutable")) + case "arkeo.arkeo.Params.ValidatorRewardsPercentage": + panic(fmt.Errorf("field ValidatorRewardsPercentage of message arkeo.arkeo.Params is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: arkeo.arkeo.Params")) @@ -187,6 +246,12 @@ func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protore // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_Params) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { + case "arkeo.arkeo.Params.CommunityPoolPercentage": + return protoreflect.ValueOfString("") + case "arkeo.arkeo.Params.DevFundPercentage": + return protoreflect.ValueOfString("") + case "arkeo.arkeo.Params.ValidatorRewardsPercentage": + return protoreflect.ValueOfString("") default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: arkeo.arkeo.Params")) @@ -256,6 +321,18 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { var n int var l int _ = l + l = len(x.CommunityPoolPercentage) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.DevFundPercentage) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.ValidatorRewardsPercentage) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -285,6 +362,27 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if len(x.ValidatorRewardsPercentage) > 0 { + i -= len(x.ValidatorRewardsPercentage) + copy(dAtA[i:], x.ValidatorRewardsPercentage) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.ValidatorRewardsPercentage))) + i-- + dAtA[i] = 0x1a + } + if len(x.DevFundPercentage) > 0 { + i -= len(x.DevFundPercentage) + copy(dAtA[i:], x.DevFundPercentage) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.DevFundPercentage))) + i-- + dAtA[i] = 0x12 + } + if len(x.CommunityPoolPercentage) > 0 { + i -= len(x.CommunityPoolPercentage) + copy(dAtA[i:], x.CommunityPoolPercentage) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.CommunityPoolPercentage))) + i-- + dAtA[i] = 0xa + } if input.Buf != nil { input.Buf = append(input.Buf, dAtA...) } else { @@ -334,6 +432,102 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field CommunityPoolPercentage", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.CommunityPoolPercentage = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field DevFundPercentage", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.DevFundPercentage = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ValidatorRewardsPercentage", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.ValidatorRewardsPercentage = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -387,6 +581,10 @@ type Params struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + CommunityPoolPercentage string `protobuf:"bytes,1,opt,name=CommunityPoolPercentage,proto3" json:"CommunityPoolPercentage,omitempty"` + DevFundPercentage string `protobuf:"bytes,2,opt,name=DevFundPercentage,proto3" json:"DevFundPercentage,omitempty"` + ValidatorRewardsPercentage string `protobuf:"bytes,3,opt,name=ValidatorRewardsPercentage,proto3" json:"ValidatorRewardsPercentage,omitempty"` } func (x *Params) Reset() { @@ -409,24 +607,69 @@ func (*Params) Descriptor() ([]byte, []int) { return file_arkeo_arkeo_params_proto_rawDescGZIP(), []int{0} } +func (x *Params) GetCommunityPoolPercentage() string { + if x != nil { + return x.CommunityPoolPercentage + } + return "" +} + +func (x *Params) GetDevFundPercentage() string { + if x != nil { + return x.DevFundPercentage + } + return "" +} + +func (x *Params) GetValidatorRewardsPercentage() string { + if x != nil { + return x.ValidatorRewardsPercentage + } + return "" +} + var File_arkeo_arkeo_params_proto protoreflect.FileDescriptor var file_arkeo_arkeo_params_proto_rawDesc = []byte{ 0x0a, 0x18, 0x61, 0x72, 0x6b, 0x65, 0x6f, 0x2f, 0x61, 0x72, 0x6b, 0x65, 0x6f, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x61, 0x72, 0x6b, 0x65, 0x6f, 0x2e, 0x61, 0x72, 0x6b, 0x65, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x0e, 0x0a, - 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x04, 0x98, 0xa0, 0x1f, 0x00, 0x42, 0x89, 0x01, - 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x72, 0x6b, 0x65, 0x6f, 0x2e, 0x61, 0x72, 0x6b, 0x65, - 0x6f, 0x42, 0x0b, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x1c, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x61, 0x72, 0x6b, 0x65, 0x6f, 0x2f, 0x61, 0x72, 0x6b, 0x65, 0x6f, 0xa2, 0x02, - 0x03, 0x41, 0x41, 0x58, 0xaa, 0x02, 0x0b, 0x41, 0x72, 0x6b, 0x65, 0x6f, 0x2e, 0x41, 0x72, 0x6b, - 0x65, 0x6f, 0xca, 0x02, 0x0b, 0x41, 0x72, 0x6b, 0x65, 0x6f, 0x5c, 0x41, 0x72, 0x6b, 0x65, 0x6f, - 0xe2, 0x02, 0x17, 0x41, 0x72, 0x6b, 0x65, 0x6f, 0x5c, 0x41, 0x72, 0x6b, 0x65, 0x6f, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0c, 0x41, 0x72, 0x6b, - 0x65, 0x6f, 0x3a, 0x3a, 0x41, 0x72, 0x6b, 0x65, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2f, 0x63, 0x6f, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe1, 0x02, 0x0a, 0x06, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x12, 0x71, 0x0a, 0x17, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, + 0x50, 0x6f, 0x6f, 0x6c, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x37, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, + 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, 0x65, 0x63, 0xd2, 0xb4, 0x2d, 0x10, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, 0x65, 0x63, 0x52, 0x17, 0x43, + 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6f, 0x6c, 0x50, 0x65, 0x72, 0x63, + 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, 0x65, 0x0a, 0x11, 0x44, 0x65, 0x76, 0x46, 0x75, 0x6e, + 0x64, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x37, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x65, 0x67, + 0x61, 0x63, 0x79, 0x44, 0x65, 0x63, 0xd2, 0xb4, 0x2d, 0x10, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, 0x65, 0x63, 0x52, 0x11, 0x44, 0x65, 0x76, 0x46, + 0x75, 0x6e, 0x64, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, 0x77, 0x0a, + 0x1a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, + 0x73, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x37, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x65, 0x67, + 0x61, 0x63, 0x79, 0x44, 0x65, 0x63, 0xd2, 0xb4, 0x2d, 0x10, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, 0x65, 0x63, 0x52, 0x1a, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x73, 0x50, 0x65, 0x72, 0x63, + 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x3a, 0x04, 0x98, 0xa0, 0x1f, 0x00, 0x42, 0x89, 0x01, 0x0a, + 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x72, 0x6b, 0x65, 0x6f, 0x2e, 0x61, 0x72, 0x6b, 0x65, 0x6f, + 0x42, 0x0b, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, + 0x1c, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x61, 0x72, 0x6b, 0x65, 0x6f, 0x2f, 0x61, 0x72, 0x6b, 0x65, 0x6f, 0xa2, 0x02, 0x03, + 0x41, 0x41, 0x58, 0xaa, 0x02, 0x0b, 0x41, 0x72, 0x6b, 0x65, 0x6f, 0x2e, 0x41, 0x72, 0x6b, 0x65, + 0x6f, 0xca, 0x02, 0x0b, 0x41, 0x72, 0x6b, 0x65, 0x6f, 0x5c, 0x41, 0x72, 0x6b, 0x65, 0x6f, 0xe2, + 0x02, 0x17, 0x41, 0x72, 0x6b, 0x65, 0x6f, 0x5c, 0x41, 0x72, 0x6b, 0x65, 0x6f, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0c, 0x41, 0x72, 0x6b, 0x65, + 0x6f, 0x3a, 0x3a, 0x41, 0x72, 0x6b, 0x65, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/app/app.go b/app/app.go index 405d9b24..9bf01528 100644 --- a/app/app.go +++ b/app/app.go @@ -201,7 +201,7 @@ var ( // module account permissions maccPerms = map[string][]string{ authtypes.FeeCollectorName: nil, - distrtypes.ModuleName: nil, + distrtypes.ModuleName: {authtypes.Minter}, icatypes.ModuleName: nil, minttypes.ModuleName: {authtypes.Minter}, stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, @@ -209,11 +209,10 @@ var ( govtypes.ModuleName: {authtypes.Burner}, ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, claimmoduletypes.ModuleName: {authtypes.Minter}, - arkeomoduletypes.ModuleName: {}, + arkeomoduletypes.ModuleName: {authtypes.Minter}, arkeomoduletypes.ReserveName: {}, arkeomoduletypes.ProviderName: {}, arkeomoduletypes.ContractName: {}, - // this line is used by starport scaffolding # stargate/app/maccPerms } ) @@ -595,6 +594,8 @@ func NewArkeoApp( *app.Keepers.StakingKeeper, govModuleAddr, logger, + app.Keepers.MintKeeper, + app.Keepers.DistrKeeper, ) /**** Module Options ****/ diff --git a/app/app_regtest.go b/app/app_regtest.go index 99c122c1..d8f23413 100644 --- a/app/app_regtest.go +++ b/app/app_regtest.go @@ -220,14 +220,14 @@ var ( // module account permissions maccPerms = map[string][]string{ authtypes.FeeCollectorName: nil, - distrtypes.ModuleName: nil, + distrtypes.ModuleName: {authtypes.Minter}, icatypes.ModuleName: nil, minttypes.ModuleName: {authtypes.Minter}, stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, govtypes.ModuleName: {authtypes.Burner}, ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, - arkeomoduletypes.ModuleName: {}, + arkeomoduletypes.ModuleName: {authtypes.Minter}, arkeomoduletypes.ReserveName: {}, arkeomoduletypes.ProviderName: {}, arkeomoduletypes.ContractName: {}, @@ -602,6 +602,8 @@ func NewArkeoApp( *app.Keepers.StakingKeeper, govModuleAddr, logger, + app.Keepers.MintKeeper, + app.Keepers.DistrKeeper, ) arkeoModule := arkeomodule.NewAppModule(appCodec, app.ArkeoKeeper, app.Keepers.AccountKeeper, app.Keepers.BankKeeper, *app.Keepers.StakingKeeper) diff --git a/proto/arkeo/arkeo/params.proto b/proto/arkeo/arkeo/params.proto index ac5f2ed6..b7a7de5f 100644 --- a/proto/arkeo/arkeo/params.proto +++ b/proto/arkeo/arkeo/params.proto @@ -2,8 +2,15 @@ syntax = "proto3"; package arkeo.arkeo; import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos_proto/cosmos.proto"; option go_package = "github.com/arkeonetwork/arkeo/x/arkeo/types"; // Params defines the parameters for the module. -message Params { option (gogoproto.goproto_stringer) = false; } +message Params { + option (gogoproto.goproto_stringer) = false; + string CommunityPoolPercentage= 1 [(cosmos_proto.scalar) = "cosmos.Int", (gogoproto.customtype) = "cosmossdk.io/math.Int", (gogoproto.nullable) = false]; + string DevFundPercentage= 2 [(cosmos_proto.scalar) = "cosmos.Int", (gogoproto.customtype) = "cosmossdk.io/math.Int", (gogoproto.nullable) = false]; + string GrantFundPercentage= 3 [(cosmos_proto.scalar) = "cosmos.Int", (gogoproto.customtype) = "cosmossdk.io/math.Int", (gogoproto.nullable) = false]; +} diff --git a/scripts/genesis.sh b/scripts/genesis.sh index fa8c5178..0fd001ca 100755 --- a/scripts/genesis.sh +++ b/scripts/genesis.sh @@ -94,6 +94,15 @@ if [ ! -f ~/.arkeo/config/genesis.json ]; then add_account "$BOB" $TOKEN 1000000000000000 # bob, 1m add_claim_records "ARKEO" "$BOB" 1000 1000 1000 true + # Add Foundational Accounts + # FoundationCommunityAccount = "tarkeo1v50hrsxx0mxar4653aujcnqyjft07w0npcxrjx" + add_account "tarkeo1v50hrsxx0mxar4653aujcnqyjft07w0npcxrjx" $TOKEN 10000 + # FoundationDevAccount = "tarkeo10sav33v67743s6cl2cvjmmua7c5arysw3txz9r" + add_account "tarkeo10sav33v67743s6cl2cvjmmua7c5arysw3txz9r" $TOKEN 10000 + # FoundationGrantsAccount = "tarkeo16k3k0erkwaanqnup20dxxenpd6wh058nh4pgup" + add_account "tarkeo16k3k0erkwaanqnup20dxxenpd6wh058nh4pgup" $TOKEN 10000 + + # Thorchain derived test addresses add_account "tarkeo1dllfyp57l4xj5umqfcqy6c2l3xfk0qk6zpc3t7" $TOKEN 1000000000000000 # bob, 10m add_claim_records "ARKEO" "tarkeo1dllfyp57l4xj5umqfcqy6c2l3xfk0qk6zpc3t7" 1000 1000 1000 true diff --git a/test/regression/mnt/exports/suites_contracts_pay-as-you-go.json b/test/regression/mnt/exports/suites_contracts_pay-as-you-go.json index d5acf54d..78d5cb9d 100644 --- a/test/regression/mnt/exports/suites_contracts_pay-as-you-go.json +++ b/test/regression/mnt/exports/suites_contracts_pay-as-you-go.json @@ -45,7 +45,11 @@ } ], "next_contract_id": "2", - "params": {}, + "params": { + "CommunityPoolPercentage": "10", + "DevFundPercentage": "20", + "GrantFundPercentage": "20" + }, "providers": [ { "bond": "1000000000000", @@ -115,10 +119,17 @@ }, "sequence": "2" }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "11", + "address": "tarkeo1v50hrsxx0mxar4653aujcnqyjft07w0npcxrjx", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { - "account_number": "9", + "account_number": "14", "address": "tarkeo1d0m97ywk2y4vq58ud6q5e0r3q9khj9e3unfe4t", "pub_key": null, "sequence": "0" @@ -126,6 +137,13 @@ "name": "arkeo-reserve", "permissions": [] }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "13", + "address": "tarkeo1w3shy6m9damxzmr0wpjhyvtgdeuhjdr8wq6hgempwfcxwvmcw5m8wdtrwu685umewp58svnv09nxudf5wd5qsks9jp", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -139,6 +157,13 @@ "burner" ] }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "10", + "address": "tarkeo10sav33v67743s6cl2cvjmmua7c5arysw3txz9r", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -148,12 +173,14 @@ "sequence": "0" }, "name": "distribution", - "permissions": [] + "permissions": [ + "minter" + ] }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { - "account_number": "10", + "account_number": "15", "address": "tarkeo1kz2dkl8zlxwte008astc5e65htrxdcse6x3h3h", "pub_key": null, "sequence": "0" @@ -161,6 +188,19 @@ "name": "contracts", "permissions": [] }, + { + "@type": "/cosmos.auth.v1beta1.ModuleAccount", + "base_account": { + "account_number": "9", + "address": "tarkeo1k8925g52vwe5jgfp4nqr7ljuhs7nzu2f8g0za5", + "pub_key": null, + "sequence": "0" + }, + "name": "arkeo", + "permissions": [ + "minter" + ] + }, { "@type": "/cosmos.auth.v1beta1.BaseAccount", "account_number": "0", @@ -171,6 +211,13 @@ }, "sequence": "1" }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "12", + "address": "tarkeo16k3k0erkwaanqnup20dxxenpd6wh058nh4pgup", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -246,6 +293,15 @@ } ] }, + { + "address": "tarkeo1v50hrsxx0mxar4653aujcnqyjft07w0npcxrjx", + "coins": [ + { + "amount": "621404328", + "denom": "uarkeo" + } + ] + }, { "address": "tarkeo1d0m97ywk2y4vq58ud6q5e0r3q9khj9e3unfe4t", "coins": [ @@ -255,11 +311,47 @@ } ] }, + { + "address": "tarkeo10sav33v67743s6cl2cvjmmua7c5arysw3txz9r", + "coins": [ + { + "amount": "643005225", + "denom": "uarkeo" + } + ] + }, { "address": "tarkeo1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8t6gr9e", "coins": [ { - "amount": "16066162928", + "amount": "15766261669", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo1k8925g52vwe5jgfp4nqr7ljuhs7nzu2f8g0za5", + "coins": [ + { + "amount": "107167575", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo1hnyy4gp5tgarpg3xu6w5cw4zsyphx2lyvls9rz", + "coins": [ + { + "amount": "1498845173", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo16k3k0erkwaanqnup20dxxenpd6wh058nh4pgup", + "coins": [ + { + "amount": "643005225", "denom": "uarkeo" } ] @@ -272,6 +364,15 @@ "denom": "uarkeo" } ] + }, + { + "address": "tarkeo1w3shy6m9damxzmr0wpjhyvtgdeuhjdr8wq6hgempwfcxwvmcw5m8wdtrwu685umewp58svnv09nxudf5wd5qsks9jp", + "coins": [ + { + "amount": "1500352", + "denom": "uarkeo" + } + ] } ], "denom_metadata": [], @@ -282,7 +383,7 @@ "send_enabled": [], "supply": [ { - "amount": "52001016066162928", + "amount": "52001019281189547", "denom": "uarkeo" } ] @@ -357,7 +458,7 @@ "fee_pool": { "community_pool": [ { - "amount": "321323258.560000000000000000", + "amount": "21421544.840000000000000000", "denom": "uarkeo" } ] @@ -366,7 +467,7 @@ { "outstanding_rewards": [ { - "amount": "15744839669.440000000000000000", + "amount": "15744840124.160000000000000000", "denom": "uarkeo" } ], @@ -385,7 +486,7 @@ "accumulated": { "commission": [ { - "amount": "1574483966.944000000000000000", + "amount": "1574484012.416000000000000000", "denom": "uarkeo" } ] @@ -399,7 +500,7 @@ "period": "2", "rewards": [ { - "amount": "14170355702.496000000000000000", + "amount": "14170356111.744000000000000000", "denom": "uarkeo" } ] @@ -574,8 +675,8 @@ }, "mint": { "minter": { - "annual_provisions": "6760124958900879.440734825593079684", - "inflation": "0.129999865570695682" + "annual_provisions": "6760125348991042.808880506171119200", + "inflation": "0.129999865570708475" }, "params": { "blocks_per_year": "6311520", diff --git a/test/regression/mnt/exports/suites_contracts_subscription.json b/test/regression/mnt/exports/suites_contracts_subscription.json index aa0f984e..0811cce4 100644 --- a/test/regression/mnt/exports/suites_contracts_subscription.json +++ b/test/regression/mnt/exports/suites_contracts_subscription.json @@ -66,7 +66,11 @@ } ], "next_contract_id": "3", - "params": {}, + "params": { + "CommunityPoolPercentage": "10", + "DevFundPercentage": "20", + "GrantFundPercentage": "20" + }, "providers": [ { "bond": "1000000000000", @@ -133,10 +137,17 @@ "pub_key": null, "sequence": "0" }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "11", + "address": "tarkeo1v50hrsxx0mxar4653aujcnqyjft07w0npcxrjx", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { - "account_number": "9", + "account_number": "14", "address": "tarkeo1d0m97ywk2y4vq58ud6q5e0r3q9khj9e3unfe4t", "pub_key": null, "sequence": "0" @@ -144,6 +155,13 @@ "name": "arkeo-reserve", "permissions": [] }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "13", + "address": "tarkeo1w3shy6m9damxzmr0wpjhyvtgdeuhjdr8wq6hgempwfcxwvmcw5m8wdtrwu685umewp58svnv09nxudf5wd5qsks9jp", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -157,6 +175,13 @@ "burner" ] }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "10", + "address": "tarkeo10sav33v67743s6cl2cvjmmua7c5arysw3txz9r", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -166,12 +191,14 @@ "sequence": "0" }, "name": "distribution", - "permissions": [] + "permissions": [ + "minter" + ] }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { - "account_number": "10", + "account_number": "15", "address": "tarkeo1kz2dkl8zlxwte008astc5e65htrxdcse6x3h3h", "pub_key": null, "sequence": "0" @@ -179,6 +206,19 @@ "name": "contracts", "permissions": [] }, + { + "@type": "/cosmos.auth.v1beta1.ModuleAccount", + "base_account": { + "account_number": "9", + "address": "tarkeo1k8925g52vwe5jgfp4nqr7ljuhs7nzu2f8g0za5", + "pub_key": null, + "sequence": "0" + }, + "name": "arkeo", + "permissions": [ + "minter" + ] + }, { "@type": "/cosmos.auth.v1beta1.BaseAccount", "account_number": "0", @@ -189,6 +229,13 @@ }, "sequence": "2" }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "12", + "address": "tarkeo16k3k0erkwaanqnup20dxxenpd6wh058nh4pgup", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -264,6 +311,15 @@ } ] }, + { + "address": "tarkeo1v50hrsxx0mxar4653aujcnqyjft07w0npcxrjx", + "coins": [ + { + "amount": "749969453", + "denom": "uarkeo" + } + ] + }, { "address": "tarkeo1d0m97ywk2y4vq58ud6q5e0r3q9khj9e3unfe4t", "coins": [ @@ -273,11 +329,47 @@ } ] }, + { + "address": "tarkeo10sav33v67743s6cl2cvjmmua7c5arysw3txz9r", + "coins": [ + { + "amount": "771606216", + "denom": "uarkeo" + } + ] + }, { "address": "tarkeo1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8t6gr9e", "coins": [ { - "amount": "19279394116", + "amount": "18915228438", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo1k8925g52vwe5jgfp4nqr7ljuhs7nzu2f8g0za5", + "coins": [ + { + "amount": "107167575", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo1hnyy4gp5tgarpg3xu6w5cw4zsyphx2lyvls9rz", + "coins": [ + { + "amount": "1820026156", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo16k3k0erkwaanqnup20dxxenpd6wh058nh4pgup", + "coins": [ + { + "amount": "771606216", "denom": "uarkeo" } ] @@ -290,6 +382,15 @@ "denom": "uarkeo" } ] + }, + { + "address": "tarkeo1w3shy6m9damxzmr0wpjhyvtgdeuhjdr8wq6hgempwfcxwvmcw5m8wdtrwu685umewp58svnv09nxudf5wd5qsks9jp", + "coins": [ + { + "amount": "1821854", + "denom": "uarkeo" + } + ] } ], "denom_metadata": [], @@ -300,7 +401,7 @@ "send_enabled": [], "supply": [ { - "amount": "52001019279394116", + "amount": "52001023137425908", "denom": "uarkeo" } ] @@ -375,7 +476,7 @@ "fee_pool": { "community_pool": [ { - "amount": "385587882.320000000000000000", + "amount": "21421541.840000000000000000", "denom": "uarkeo" } ] @@ -384,7 +485,7 @@ { "outstanding_rewards": [ { - "amount": "18893806233.680000000000000000", + "amount": "18893806896.160000000000000000", "denom": "uarkeo" } ], @@ -403,7 +504,7 @@ "accumulated": { "commission": [ { - "amount": "1889380623.368000000000000000", + "amount": "1889380689.616000000000000000", "denom": "uarkeo" } ] @@ -417,7 +518,7 @@ "period": "2", "rewards": [ { - "amount": "17004425610.312000000000000000", + "amount": "17004426206.544000000000000000", "denom": "uarkeo" } ] @@ -592,8 +693,8 @@ }, "mint": { "minter": { - "annual_provisions": "6760123978529236.587874847213850985", - "inflation": "0.129999838684851257" + "annual_provisions": "6760124452210194.355441603119737810", + "inflation": "0.129999838684869898" }, "params": { "blocks_per_year": "6311520", diff --git a/test/regression/mnt/exports/suites_core_send.json b/test/regression/mnt/exports/suites_core_send.json index 70b02506..39ae93ec 100644 --- a/test/regression/mnt/exports/suites_core_send.json +++ b/test/regression/mnt/exports/suites_core_send.json @@ -6,7 +6,11 @@ "contract_expiration_sets": [], "contracts": [], "next_contract_id": "1", - "params": {}, + "params": { + "CommunityPoolPercentage": "10", + "DevFundPercentage": "20", + "GrantFundPercentage": "20" + }, "providers": [], "user_contract_sets": [], "version": "0" @@ -48,6 +52,20 @@ "pub_key": null, "sequence": "0" }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "11", + "address": "tarkeo1v50hrsxx0mxar4653aujcnqyjft07w0npcxrjx", + "pub_key": null, + "sequence": "0" + }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "13", + "address": "tarkeo1w3shy6m9damxzmr0wpjhyvtgdeuhjdr8wq6hgempwfcxwvmcw5m8wdtrwu685umewp58svnv09nxudf5wd5qsks9jp", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -61,6 +79,13 @@ "burner" ] }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "10", + "address": "tarkeo10sav33v67743s6cl2cvjmmua7c5arysw3txz9r", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -70,7 +95,22 @@ "sequence": "0" }, "name": "distribution", - "permissions": [] + "permissions": [ + "minter" + ] + }, + { + "@type": "/cosmos.auth.v1beta1.ModuleAccount", + "base_account": { + "account_number": "9", + "address": "tarkeo1k8925g52vwe5jgfp4nqr7ljuhs7nzu2f8g0za5", + "pub_key": null, + "sequence": "0" + }, + "name": "arkeo", + "permissions": [ + "minter" + ] }, { "@type": "/cosmos.auth.v1beta1.BaseAccount", @@ -82,6 +122,13 @@ }, "sequence": "1" }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "12", + "address": "tarkeo16k3k0erkwaanqnup20dxxenpd6wh058nh4pgup", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -148,11 +195,56 @@ } ] }, + { + "address": "tarkeo1v50hrsxx0mxar4653aujcnqyjft07w0npcxrjx", + "coins": [ + { + "amount": "64299303", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo10sav33v67743s6cl2cvjmmua7c5arysw3txz9r", + "coins": [ + { + "amount": "128598609", + "denom": "uarkeo" + } + ] + }, { "address": "tarkeo1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8t6gr9e", "coins": [ { - "amount": "3213171726", + "amount": "3213171739", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo1k8925g52vwe5jgfp4nqr7ljuhs7nzu2f8g0za5", + "coins": [ + { + "amount": "107165513", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo1hnyy4gp5tgarpg3xu6w5cw4zsyphx2lyvls9rz", + "coins": [ + { + "amount": "214116679", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo16k3k0erkwaanqnup20dxxenpd6wh058nh4pgup", + "coins": [ + { + "amount": "128598609", "denom": "uarkeo" } ] @@ -165,6 +257,15 @@ "denom": "uarkeo" } ] + }, + { + "address": "tarkeo1w3shy6m9damxzmr0wpjhyvtgdeuhjdr8wq6hgempwfcxwvmcw5m8wdtrwu685umewp58svnv09nxudf5wd5qsks9jp", + "coins": [ + { + "amount": "214332", + "denom": "uarkeo" + } + ] } ], "denom_metadata": [], @@ -175,7 +276,7 @@ "send_enabled": [], "supply": [ { - "amount": "52000003213171726", + "amount": "52000003856164784", "denom": "uarkeo" } ] @@ -250,7 +351,7 @@ "fee_pool": { "community_pool": [ { - "amount": "64263434.520000000000000000", + "amount": "64263434.780000000000000000", "denom": "uarkeo" } ] @@ -259,7 +360,7 @@ { "outstanding_rewards": [ { - "amount": "3148908291.480000000000000000", + "amount": "3148908304.220000000000000000", "denom": "uarkeo" } ], @@ -278,7 +379,7 @@ "accumulated": { "commission": [ { - "amount": "314890829.148000000000000000", + "amount": "314890830.422000000000000000", "denom": "uarkeo" } ] @@ -292,7 +393,7 @@ "period": "2", "rewards": [ { - "amount": "2834017462.332000000000000000", + "amount": "2834017473.798000000000000000", "denom": "uarkeo" } ] @@ -467,8 +568,8 @@ }, "mint": { "minter": { - "annual_provisions": "6759998880320819.659730123458173168", - "inflation": "0.129999973112422838" + "annual_provisions": "6759998936046892.886047279891762320", + "inflation": "0.129999973112423204" }, "params": { "blocks_per_year": "6311520", diff --git a/test/regression/mnt/exports/suites_initialize.json b/test/regression/mnt/exports/suites_initialize.json index 62ebbcdf..8faee0d3 100644 --- a/test/regression/mnt/exports/suites_initialize.json +++ b/test/regression/mnt/exports/suites_initialize.json @@ -6,7 +6,11 @@ "contract_expiration_sets": [], "contracts": [], "next_contract_id": "1", - "params": {}, + "params": { + "CommunityPoolPercentage": "10", + "DevFundPercentage": "20", + "GrantFundPercentage": "20" + }, "providers": [], "user_contract_sets": [], "version": "0" @@ -48,6 +52,20 @@ "pub_key": null, "sequence": "0" }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "11", + "address": "tarkeo1v50hrsxx0mxar4653aujcnqyjft07w0npcxrjx", + "pub_key": null, + "sequence": "0" + }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "13", + "address": "tarkeo1w3shy6m9damxzmr0wpjhyvtgdeuhjdr8wq6hgempwfcxwvmcw5m8wdtrwu685umewp58svnv09nxudf5wd5qsks9jp", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -61,6 +79,13 @@ "burner" ] }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "10", + "address": "tarkeo10sav33v67743s6cl2cvjmmua7c5arysw3txz9r", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -70,7 +95,22 @@ "sequence": "0" }, "name": "distribution", - "permissions": [] + "permissions": [ + "minter" + ] + }, + { + "@type": "/cosmos.auth.v1beta1.ModuleAccount", + "base_account": { + "account_number": "9", + "address": "tarkeo1k8925g52vwe5jgfp4nqr7ljuhs7nzu2f8g0za5", + "pub_key": null, + "sequence": "0" + }, + "name": "arkeo", + "permissions": [ + "minter" + ] }, { "@type": "/cosmos.auth.v1beta1.BaseAccount", @@ -82,6 +122,13 @@ }, "sequence": "2" }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "12", + "address": "tarkeo16k3k0erkwaanqnup20dxxenpd6wh058nh4pgup", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -140,7 +187,25 @@ "address": "tarkeo1v0n7wer498vqq6yddkr4clg3lck7kaw9lstp4k", "coins": [ { - "amount": "1000000000000000", + "amount": "1000000001000000", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo1v50hrsxx0mxar4653aujcnqyjft07w0npcxrjx", + "coins": [ + { + "amount": "42866203", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo10sav33v67743s6cl2cvjmmua7c5arysw3txz9r", + "coins": [ + { + "amount": "85732408", "denom": "uarkeo" } ] @@ -149,7 +214,34 @@ "address": "tarkeo1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8t6gr9e", "coins": [ { - "amount": "2142114536", + "amount": "2142114540", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo1k8925g52vwe5jgfp4nqr7ljuhs7nzu2f8g0za5", + "coins": [ + { + "amount": "107165513", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo1hnyy4gp5tgarpg3xu6w5cw4zsyphx2lyvls9rz", + "coins": [ + { + "amount": "106058342", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo16k3k0erkwaanqnup20dxxenpd6wh058nh4pgup", + "coins": [ + { + "amount": "85732408", "denom": "uarkeo" } ] @@ -162,6 +254,15 @@ "denom": "uarkeo" } ] + }, + { + "address": "tarkeo1w3shy6m9damxzmr0wpjhyvtgdeuhjdr8wq6hgempwfcxwvmcw5m8wdtrwu685umewp58svnv09nxudf5wd5qsks9jp", + "coins": [ + { + "amount": "107166", + "denom": "uarkeo" + } + ] } ], "denom_metadata": [], @@ -172,7 +273,7 @@ "send_enabled": [], "supply": [ { - "amount": "52000002142114536", + "amount": "52000002570776580", "denom": "uarkeo" } ] @@ -247,7 +348,7 @@ "fee_pool": { "community_pool": [ { - "amount": "42842290.720000000000000000", + "amount": "42842290.800000000000000000", "denom": "uarkeo" } ] @@ -256,7 +357,7 @@ { "outstanding_rewards": [ { - "amount": "2099272245.280000000000000000", + "amount": "2099272249.200000000000000000", "denom": "uarkeo" } ], @@ -275,7 +376,7 @@ "accumulated": { "commission": [ { - "amount": "209927224.528000000000000000", + "amount": "209927224.920000000000000000", "denom": "uarkeo" } ] @@ -289,7 +390,7 @@ "period": "2", "rewards": [ { - "amount": "1889345020.752000000000000000", + "amount": "1889345024.280000000000000000", "denom": "uarkeo" } ] @@ -464,8 +565,8 @@ }, "mint": { "minter": { - "annual_provisions": "6759999207134722.421242256517847300", - "inflation": "0.129999982074947950" + "annual_provisions": "6759999234997758.173347634280370968", + "inflation": "0.129999982074948072" }, "params": { "blocks_per_year": "6311520", diff --git a/test/regression/mnt/exports/suites_providers_providers.json b/test/regression/mnt/exports/suites_providers_providers.json index 134dcd76..4b1a06b9 100644 --- a/test/regression/mnt/exports/suites_providers_providers.json +++ b/test/regression/mnt/exports/suites_providers_providers.json @@ -6,7 +6,11 @@ "contract_expiration_sets": [], "contracts": [], "next_contract_id": "1", - "params": {}, + "params": { + "CommunityPoolPercentage": "10", + "DevFundPercentage": "20", + "GrantFundPercentage": "20" + }, "providers": [], "user_contract_sets": [], "version": "0" @@ -16,7 +20,7 @@ { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { - "account_number": "9", + "account_number": "14", "address": "tarkeo1rcvm4v5mcepj53fh2526uve0tly4grdsx5yw7k", "pub_key": null, "sequence": "0" @@ -62,6 +66,20 @@ }, "sequence": "5" }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "11", + "address": "tarkeo1v50hrsxx0mxar4653aujcnqyjft07w0npcxrjx", + "pub_key": null, + "sequence": "0" + }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "13", + "address": "tarkeo1w3shy6m9damxzmr0wpjhyvtgdeuhjdr8wq6hgempwfcxwvmcw5m8wdtrwu685umewp58svnv09nxudf5wd5qsks9jp", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -75,6 +93,13 @@ "burner" ] }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "10", + "address": "tarkeo10sav33v67743s6cl2cvjmmua7c5arysw3txz9r", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -84,7 +109,22 @@ "sequence": "0" }, "name": "distribution", - "permissions": [] + "permissions": [ + "minter" + ] + }, + { + "@type": "/cosmos.auth.v1beta1.ModuleAccount", + "base_account": { + "account_number": "9", + "address": "tarkeo1k8925g52vwe5jgfp4nqr7ljuhs7nzu2f8g0za5", + "pub_key": null, + "sequence": "0" + }, + "name": "arkeo", + "permissions": [ + "minter" + ] }, { "@type": "/cosmos.auth.v1beta1.BaseAccount", @@ -96,6 +136,13 @@ }, "sequence": "1" }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "12", + "address": "tarkeo16k3k0erkwaanqnup20dxxenpd6wh058nh4pgup", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -159,11 +206,56 @@ } ] }, + { + "address": "tarkeo1v50hrsxx0mxar4653aujcnqyjft07w0npcxrjx", + "coins": [ + { + "amount": "257125458", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo10sav33v67743s6cl2cvjmmua7c5arysw3txz9r", + "coins": [ + { + "amount": "257197200", + "denom": "uarkeo" + } + ] + }, { "address": "tarkeo1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8t6gr9e", "coins": [ { - "amount": "6426342986", + "amount": "6297816191", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo1k8925g52vwe5jgfp4nqr7ljuhs7nzu2f8g0za5", + "coins": [ + { + "amount": "107165513", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo1hnyy4gp5tgarpg3xu6w5cw4zsyphx2lyvls9rz", + "coins": [ + { + "amount": "535291663", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo16k3k0erkwaanqnup20dxxenpd6wh058nh4pgup", + "coins": [ + { + "amount": "257197200", "denom": "uarkeo" } ] @@ -176,6 +268,15 @@ "denom": "uarkeo" } ] + }, + { + "address": "tarkeo1w3shy6m9damxzmr0wpjhyvtgdeuhjdr8wq6hgempwfcxwvmcw5m8wdtrwu685umewp58svnv09nxudf5wd5qsks9jp", + "coins": [ + { + "amount": "535827", + "denom": "uarkeo" + } + ] } ], "denom_metadata": [], @@ -186,7 +287,7 @@ "send_enabled": [], "supply": [ { - "amount": "52000006426342986", + "amount": "52000007712329052", "denom": "uarkeo" } ] @@ -261,7 +362,7 @@ "fee_pool": { "community_pool": [ { - "amount": "128526859.720000000000000000", + "amount": "0.040000000000000000", "denom": "uarkeo" } ] @@ -270,7 +371,7 @@ { "outstanding_rewards": [ { - "amount": "6297816126.280000000000000000", + "amount": "6297816190.960000000000000000", "denom": "uarkeo" } ], @@ -289,7 +390,7 @@ "accumulated": { "commission": [ { - "amount": "629781612.628000000000000000", + "amount": "629781619.096000000000000000", "denom": "uarkeo" } ] @@ -303,7 +404,7 @@ "period": "2", "rewards": [ { - "amount": "5668034513.652000000000000000", + "amount": "5668034571.864000000000000000", "denom": "uarkeo" } ] @@ -478,8 +579,8 @@ }, "mint": { "minter": { - "annual_provisions": "6759997899879145.760700882792909356", - "inflation": "0.129999946224851156" + "annual_provisions": "6759998039194342.158301786339003680", + "inflation": "0.129999946224852984" }, "params": { "blocks_per_year": "6311520", diff --git a/test/regression/mnt/exports/suites_sentinel_contract_config.json b/test/regression/mnt/exports/suites_sentinel_contract_config.json index 5f4d7d96..b3e3034f 100644 --- a/test/regression/mnt/exports/suites_sentinel_contract_config.json +++ b/test/regression/mnt/exports/suites_sentinel_contract_config.json @@ -70,7 +70,11 @@ } ], "next_contract_id": "1", - "params": {}, + "params": { + "CommunityPoolPercentage": "10", + "DevFundPercentage": "20", + "GrantFundPercentage": "20" + }, "providers": [ { "bond": "1000000000000", @@ -137,6 +141,13 @@ "pub_key": null, "sequence": "0" }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "11", + "address": "tarkeo1v50hrsxx0mxar4653aujcnqyjft07w0npcxrjx", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -150,6 +161,13 @@ "burner" ] }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "10", + "address": "tarkeo10sav33v67743s6cl2cvjmmua7c5arysw3txz9r", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -159,7 +177,22 @@ "sequence": "0" }, "name": "distribution", - "permissions": [] + "permissions": [ + "minter" + ] + }, + { + "@type": "/cosmos.auth.v1beta1.ModuleAccount", + "base_account": { + "account_number": "9", + "address": "tarkeo1k8925g52vwe5jgfp4nqr7ljuhs7nzu2f8g0za5", + "pub_key": null, + "sequence": "0" + }, + "name": "arkeo", + "permissions": [ + "minter" + ] }, { "@type": "/cosmos.auth.v1beta1.BaseAccount", @@ -171,6 +204,13 @@ }, "sequence": "1" }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "12", + "address": "tarkeo16k3k0erkwaanqnup20dxxenpd6wh058nh4pgup", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -243,6 +283,24 @@ } ] }, + { + "address": "tarkeo1v50hrsxx0mxar4653aujcnqyjft07w0npcxrjx", + "coins": [ + { + "amount": "21433514", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo10sav33v67743s6cl2cvjmmua7c5arysw3txz9r", + "coins": [ + { + "amount": "42867029", + "denom": "uarkeo" + } + ] + }, { "address": "tarkeo1kz2dkl8zlxwte008astc5e65htrxdcse6x3h3h", "coins": [ @@ -252,6 +310,24 @@ } ] }, + { + "address": "tarkeo1k8925g52vwe5jgfp4nqr7ljuhs7nzu2f8g0za5", + "coins": [ + { + "amount": "107167575", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo16k3k0erkwaanqnup20dxxenpd6wh058nh4pgup", + "coins": [ + { + "amount": "42867029", + "denom": "uarkeo" + } + ] + }, { "address": "tarkeo1uhapc6jjq6ns0ydnk7zld5x7f5kl2ukemjw5fg", "coins": [ @@ -279,7 +355,7 @@ "send_enabled": [], "supply": [ { - "amount": "52001001071078191", + "amount": "52001001285413338", "denom": "uarkeo" } ] diff --git a/test/regression/mnt/exports/suites_sentinel_sentinel.json b/test/regression/mnt/exports/suites_sentinel_sentinel.json index 87936117..4ce43644 100644 --- a/test/regression/mnt/exports/suites_sentinel_sentinel.json +++ b/test/regression/mnt/exports/suites_sentinel_sentinel.json @@ -6,7 +6,11 @@ "contract_expiration_sets": [], "contracts": [], "next_contract_id": "1", - "params": {}, + "params": { + "CommunityPoolPercentage": "10", + "DevFundPercentage": "20", + "GrantFundPercentage": "20" + }, "providers": [], "user_contract_sets": [], "version": "0" @@ -48,6 +52,13 @@ "pub_key": null, "sequence": "0" }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "11", + "address": "tarkeo1v50hrsxx0mxar4653aujcnqyjft07w0npcxrjx", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -61,6 +72,13 @@ "burner" ] }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "10", + "address": "tarkeo10sav33v67743s6cl2cvjmmua7c5arysw3txz9r", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -70,7 +88,22 @@ "sequence": "0" }, "name": "distribution", - "permissions": [] + "permissions": [ + "minter" + ] + }, + { + "@type": "/cosmos.auth.v1beta1.ModuleAccount", + "base_account": { + "account_number": "9", + "address": "tarkeo1k8925g52vwe5jgfp4nqr7ljuhs7nzu2f8g0za5", + "pub_key": null, + "sequence": "0" + }, + "name": "arkeo", + "permissions": [ + "minter" + ] }, { "@type": "/cosmos.auth.v1beta1.BaseAccount", @@ -82,6 +115,13 @@ }, "sequence": "1" }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "account_number": "12", + "address": "tarkeo16k3k0erkwaanqnup20dxxenpd6wh058nh4pgup", + "pub_key": null, + "sequence": "0" + }, { "@type": "/cosmos.auth.v1beta1.ModuleAccount", "base_account": { @@ -145,6 +185,42 @@ } ] }, + { + "address": "tarkeo1v50hrsxx0mxar4653aujcnqyjft07w0npcxrjx", + "coins": [ + { + "amount": "21433102", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo10sav33v67743s6cl2cvjmmua7c5arysw3txz9r", + "coins": [ + { + "amount": "42866205", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo1k8925g52vwe5jgfp4nqr7ljuhs7nzu2f8g0za5", + "coins": [ + { + "amount": "107165513", + "denom": "uarkeo" + } + ] + }, + { + "address": "tarkeo16k3k0erkwaanqnup20dxxenpd6wh058nh4pgup", + "coins": [ + { + "amount": "42866205", + "denom": "uarkeo" + } + ] + }, { "address": "tarkeo1uhapc6jjq6ns0ydnk7zld5x7f5kl2ukemjw5fg", "coins": [ @@ -172,7 +248,7 @@ "send_enabled": [], "supply": [ { - "amount": "52000001071057294", + "amount": "52000001285388319", "denom": "uarkeo" } ] diff --git a/test/regression/suites/contracts/subscription.yaml b/test/regression/suites/contracts/subscription.yaml index ac5c0d62..875db64c 100644 --- a/test/regression/suites/contracts/subscription.yaml +++ b/test/regression/suites/contracts/subscription.yaml @@ -111,8 +111,8 @@ asserts: - .client_pubkey == "tarkeopub1addwnpepq2res6tu0m73ulk5sepgp6g3y37schfgymxy8z6l3lc78k7ju9u45yajwem" - .contract_type == "SUBSCRIPTION" - .settlement_duration == 11 - - .paid == 100 - - .reserve_contrib_asset == 10 + - .paid == 0 + - .reserve_contrib_asset == 0 # - .reserve_contrib_usd == 10 # TODO --- ######################################################################################## diff --git a/testutil/keeper/arkeo.go b/testutil/keeper/arkeo.go index 3b975de8..05f7b8d7 100644 --- a/testutil/keeper/arkeo.go +++ b/testutil/keeper/arkeo.go @@ -8,6 +8,8 @@ import ( storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/runtime" authcodec "github.com/cosmos/cosmos-sdk/x/auth/codec" + distkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" + disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types" "github.com/arkeonetwork/arkeo/common" "github.com/arkeonetwork/arkeo/common/cosmos" @@ -27,6 +29,8 @@ import ( bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" typesparams "github.com/cosmos/cosmos-sdk/x/params/types" @@ -43,6 +47,8 @@ func ArkeoKeeper(t testing.TB) (cosmos.Context, keeper.Keeper) { keyParams := cosmos.NewKVStoreKey(paramstypes.StoreKey) tkeyParams := cosmos.NewTransientStoreKey(paramstypes.TStoreKey) memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) + keyMint := cosmos.NewKVStoreKey(minttypes.StoreKey) + keydist := cosmos.NewKVStoreKey(disttypes.StoreKey) logger := log.NewNopLogger() db := tmdb.NewMemDB() @@ -70,12 +76,14 @@ func ArkeoKeeper(t testing.TB) (cosmos.Context, keeper.Keeper) { runtime.NewKVStoreService(keyAcc), authtypes.ProtoBaseAccount, map[string][]string{ + disttypes.ModuleName: {authtypes.Minter}, stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, types.ModuleName: {authtypes.Minter, authtypes.Burner}, types.ReserveName: {}, types.ProviderName: {}, types.ContractName: {}, + minttypes.ModuleName: {authtypes.Minter}, }, authcodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()), sdk.Bech32PrefixAccAddr, @@ -100,6 +108,27 @@ func ArkeoKeeper(t testing.TB) (cosmos.Context, keeper.Keeper) { authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), ) + + dk := distkeeper.NewKeeper( + cdc, + runtime.NewKVStoreService(keydist), + ak, + bk, + sk, + authtypes.FeeCollectorName, + govModuleAddr, + ) + + mk := mintkeeper.NewKeeper( + cdc, + runtime.NewKVStoreService(keyMint), + sk, + ak, + bk, + authtypes.FeeCollectorName, + govModuleAddr, + ) + k := keeper.NewKVStore( cdc, storeKey, @@ -110,6 +139,8 @@ func ArkeoKeeper(t testing.TB) (cosmos.Context, keeper.Keeper) { *sk, govModuleAddr, logger, + mk, + dk, ) ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger()) diff --git a/x/arkeo/keeper/keeper.go b/x/arkeo/keeper/keeper.go index d7fd6896..a1900d1e 100644 --- a/x/arkeo/keeper/keeper.go +++ b/x/arkeo/keeper/keeper.go @@ -7,12 +7,17 @@ import ( "cosmossdk.io/errors" "cosmossdk.io/log" + "cosmossdk.io/math" + sdkmath "cosmossdk.io/math" storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + distkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/keeper" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -58,6 +63,10 @@ type Keeper interface { GetActiveValidators(ctx cosmos.Context) ([]stakingtypes.Validator, error) GetAccount(ctx cosmos.Context, addr cosmos.AccAddress) cosmos.Account StakingSetParams(ctx cosmos.Context, params stakingtypes.Params) error + MintAndDistributeTokens(ctx cosmos.Context, newlyMinted cosmos.Coin) (cosmos.Coin, error) + GetCirculatingSupply(ctx cosmos.Context, denom string) (cosmos.Coin, error) + GetInflationRate(ctx cosmos.Context) (math.LegacyDec, error) + MoveTokensFromDistributionToFoundationPoolAccount(ctx cosmos.Context) error // Query Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) @@ -110,15 +119,17 @@ const ( ) type KVStore struct { - cdc codec.BinaryCodec - storeKey storetypes.StoreKey - memKey storetypes.StoreKey - paramstore paramtypes.Subspace - coinKeeper bankkeeper.Keeper - accountKeeper authkeeper.AccountKeeper - stakingKeeper stakingkeeper.Keeper - authority string - logger log.Logger + cdc codec.BinaryCodec + storeKey storetypes.StoreKey + memKey storetypes.StoreKey + paramstore paramtypes.Subspace + coinKeeper bankkeeper.Keeper + accountKeeper authkeeper.AccountKeeper + stakingKeeper stakingkeeper.Keeper + authority string + logger log.Logger + mintKeeper minttypes.Keeper + distributionKeeper distkeeper.Keeper } func NewKVStore( @@ -131,6 +142,8 @@ func NewKVStore( stakingKeeper stakingkeeper.Keeper, authority string, logger log.Logger, + mintKeeper minttypes.Keeper, + distributionKeeper distkeeper.Keeper, ) *KVStore { // set KeyTable if it has not already been set if !ps.HasKeyTable() { @@ -138,15 +151,17 @@ func NewKVStore( } return &KVStore{ - cdc: cdc, - storeKey: storeKey, - memKey: memKey, - paramstore: ps, - coinKeeper: coinKeeper, - accountKeeper: accountKeeper, - stakingKeeper: stakingKeeper, - authority: authority, - logger: logger, + cdc: cdc, + storeKey: storeKey, + memKey: memKey, + paramstore: ps, + coinKeeper: coinKeeper, + accountKeeper: accountKeeper, + stakingKeeper: stakingKeeper, + authority: authority, + logger: logger, + mintKeeper: mintKeeper, + distributionKeeper: distributionKeeper, } } @@ -360,3 +375,154 @@ func (k KVStore) StakingSetParams(ctx cosmos.Context, params stakingtypes.Params func (k KVStore) GetAuthority() string { return k.authority } + +func (k KVStore) GetCirculatingSupply(ctx cosmos.Context, denom string) (cosmos.Coin, error) { + sdkContext := sdk.UnwrapSDKContext(ctx) + + // Get Total Supply + fullTokenSupply, err := k.coinKeeper.TotalSupply(ctx, &banktypes.QueryTotalSupplyRequest{}) + if err != nil { + sdkContext.Logger().Error("Failed to get full token supply data", err) + return cosmos.NewCoin(denom, sdkmath.NewInt(0)), err + } + totalSupply := fullTokenSupply.Supply.AmountOf(configs.Denom) + sdkContext.Logger().Info(fmt.Sprintf("current supply of token with denom :%s : supply : %d", denom, totalSupply.Int64())) + + // Get the account addresses whose balances need to be exempted + devAccountAddress, err := k.getFoundationDevAccountAddress() + if err != nil { + return cosmos.NewCoin(denom, sdkmath.NewInt(0)), fmt.Errorf("failed to fetch foundational account %s", err) + } + + communityAccountAddress, err := k.getFoundationCommunityAccountAddress() + if err != nil { + return cosmos.NewCoin(denom, sdkmath.NewInt(0)), fmt.Errorf("failed to fetch foundational account %s", err) + } + + grantAccountAddress, err := k.getFoundationGrantsAccountAddress() + if err != nil { + return cosmos.NewCoin(denom, sdkmath.NewInt(0)), fmt.Errorf("failed to fetch foundational account %s", err) + } + + // Module Address for which the circulating supply should be exempted + moduleAddressToExempt := []sdk.AccAddress{ + devAccountAddress, + communityAccountAddress, + grantAccountAddress, + } + + exemptBalance := cosmos.NewInt(0) + + // range over the module and create exempt balances + for _, moduleAddress := range moduleAddressToExempt { + moduleBalance := k.coinKeeper.GetBalance(ctx, moduleAddress, denom) + exemptBalance = exemptBalance.Add(moduleBalance.Amount) + } + + // total supply without balances of exempted module + circulatingSupply := totalSupply.Sub(exemptBalance) + + return cosmos.NewCoin(denom, circulatingSupply), nil +} + +func (k KVStore) MintAndDistributeTokens(ctx cosmos.Context, newlyMinted cosmos.Coin) (sdk.Coin, error) { + sdkContext := sdk.UnwrapSDKContext(ctx) + + params := k.GetParams(ctx) + newlyMintedAmount := newlyMinted.Amount + + // mint newly added tokens to reserve + if err := k.MintToModule(ctx, types.ModuleName, newlyMinted); err != nil { + sdkContext.Logger().Error(fmt.Sprintf("failed to mint %s", err)) + return cosmos.NewCoin(newlyMinted.Denom, sdkmath.NewInt(0)), err + } + + devFundAmount := newlyMintedAmount.Mul(params.DevFundPercentage).Quo(sdkmath.NewInt(100)) + communityPoolAmount := newlyMintedAmount.Mul(params.CommunityPoolPercentage).Quo(sdkmath.NewInt(100)) + grantFundAmount := newlyMintedAmount.Mul(params.GrantFundPercentage).Quo(sdkmath.NewInt(100)) + + devAccountAddress, err := k.getFoundationDevAccountAddress() + if err != nil { + sdkContext.Logger().Error(fmt.Sprintf("failed to fetch foundational account %s", err)) + return cosmos.NewCoin(newlyMinted.Denom, sdkmath.NewInt(0)), fmt.Errorf("failed to fetch foundational account %s", err) + } + + communityAccountAddress, err := k.getFoundationCommunityAccountAddress() + if err != nil { + sdkContext.Logger().Error(fmt.Sprintf("failed to fetch foundational account %s", err)) + return cosmos.NewCoin(newlyMinted.Denom, sdkmath.NewInt(0)), fmt.Errorf("failed to fetch foundational account %s", err) + } + + grantAccountAddress, err := k.getFoundationGrantsAccountAddress() + if err != nil { + sdkContext.Logger().Error(fmt.Sprintf("failed to fetch foundational account %s", err)) + return cosmos.NewCoin(newlyMinted.Denom, sdkmath.NewInt(0)), fmt.Errorf("failed to fetch foundational account %s", err) + } + + if err := k.SendFromModuleToAccount(ctx, types.ModuleName, devAccountAddress, cosmos.NewCoins(cosmos.NewCoin(newlyMinted.Denom, devFundAmount))); err != nil { + sdkContext.Logger().Error(fmt.Sprintf("failed to send amount to Dev foundational account %s", err)) + return cosmos.NewCoin(newlyMinted.Denom, sdkmath.NewInt(0)), fmt.Errorf("error sending amount to module %s", err) + } + + if err := k.SendFromModuleToAccount(ctx, types.ModuleName, communityAccountAddress, cosmos.NewCoins(cosmos.NewCoin(newlyMinted.Denom, communityPoolAmount))); err != nil { + sdkContext.Logger().Error(fmt.Sprintf("failed to send amount to Community foundational account %s", err)) + return cosmos.NewCoin(newlyMinted.Denom, sdkmath.NewInt(0)), fmt.Errorf("error sending amount to module %s", err) + } + + if err := k.SendFromModuleToAccount(ctx, types.ModuleName, grantAccountAddress, cosmos.NewCoins(cosmos.NewCoin(newlyMinted.Denom, grantFundAmount))); err != nil { + sdkContext.Logger().Error(fmt.Sprintf("failed to send amount to Grant foundational account %s", err)) + return cosmos.NewCoin(newlyMinted.Denom, sdkmath.NewInt(0)), fmt.Errorf("error sending amount to module %s", err) + } + + balance := newlyMintedAmount.Sub(devFundAmount).Sub(communityPoolAmount).Sub(grantFundAmount) + return cosmos.NewCoin(newlyMinted.Denom, balance), nil +} + +func (k KVStore) GetInflationRate(ctx cosmos.Context) (math.LegacyDec, error) { + minter, err := k.mintKeeper.Minter.Get(ctx) + if err != nil { + return math.LegacyNewDec(0), err + } + + return minter.Inflation, nil +} + +// transfer tokens form the Distribution to Foundation Community Pool +func (k KVStore) MoveTokensFromDistributionToFoundationPoolAccount(ctx cosmos.Context) error { + // get pool balance + pool, err := k.distributionKeeper.FeePool.Get(ctx) + if err != nil { + return err + } + amount := pool.CommunityPool.AmountOf(configs.Denom) + + communityAccountAddress, err := k.getFoundationCommunityAccountAddress() + if err != nil { + return fmt.Errorf("failed to fetch foundational account %s", err) + } + + if amount.RoundInt64() > 0 { + if err := k.distributionKeeper.DistributeFromFeePool(ctx, cosmos.NewCoins(cosmos.NewCoin(configs.Denom, amount.RoundInt())), communityAccountAddress); err != nil { + if err.Error() == "community pool does not have sufficient coins to distribute" { + ctx.Logger().Info(fmt.Sprintf("%s", err)) + return nil + } else { + ctx.Logger().Error(fmt.Sprintf("failed to distribute from community pool %s", err)) + return err + } + } + } + return nil +} + +func (k KVStore) getFoundationDevAccountAddress() (cosmos.AccAddress, error) { + return sdk.AccAddressFromBech32(types.FoundationDevAccount) +} + +func (k KVStore) getFoundationCommunityAccountAddress() (cosmos.AccAddress, error) { + return sdk.AccAddressFromBech32(types.FoundationCommunityAccount) +} + +func (k KVStore) getFoundationGrantsAccountAddress() (cosmos.AccAddress, error) { + return sdk.AccAddressFromBech32(types.FoundationGrantsAccount) +} diff --git a/x/arkeo/keeper/keeper_test.go b/x/arkeo/keeper/keeper_test.go index 92b53213..e30fe16b 100644 --- a/x/arkeo/keeper/keeper_test.go +++ b/x/arkeo/keeper/keeper_test.go @@ -3,6 +3,7 @@ package keeper import ( "testing" + math "cosmossdk.io/math" storemetrics "cosmossdk.io/store/metrics" "github.com/cosmos/cosmos-sdk/runtime" "github.com/stretchr/testify/require" @@ -11,6 +12,7 @@ import ( "github.com/arkeonetwork/arkeo/common" "github.com/arkeonetwork/arkeo/common/cosmos" "github.com/arkeonetwork/arkeo/testutil/utils" + "github.com/arkeonetwork/arkeo/x/arkeo/configs" "github.com/arkeonetwork/arkeo/x/arkeo/types" "cosmossdk.io/log" @@ -24,7 +26,12 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + distkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" typesparams "github.com/cosmos/cosmos-sdk/x/params/types" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" @@ -32,7 +39,7 @@ import ( ) const ( - bech32Prefix = "arkeo" + bech32Prefix = "tarkeo" ) var ( @@ -51,8 +58,10 @@ func SetupKeeper(t testing.TB) (cosmos.Context, Keeper) { keyBank := cosmos.NewKVStoreKey(banktypes.StoreKey) keyStake := cosmos.NewKVStoreKey(stakingtypes.StoreKey) keyParams := cosmos.NewKVStoreKey(typesparams.StoreKey) + keyMint := cosmos.NewKVStoreKey(minttypes.StoreKey) tkeyParams := cosmos.NewTransientStoreKey(typesparams.TStoreKey) memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) + keydist := cosmos.NewKVStoreKey(disttypes.StoreKey) cfg := sdk.GetConfig() @@ -92,12 +101,14 @@ func SetupKeeper(t testing.TB) (cosmos.Context, Keeper) { runtime.NewKVStoreService(keyAcc), authtypes.ProtoBaseAccount, map[string][]string{ + distrtypes.ModuleName: {authtypes.Minter}, stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, types.ModuleName: {authtypes.Minter, authtypes.Burner}, types.ReserveName: {}, types.ProviderName: {}, types.ContractName: {}, + minttypes.ModuleName: {authtypes.Minter}, }, authcodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()), sdk.Bech32PrefixAccAddr, @@ -123,6 +134,25 @@ func SetupKeeper(t testing.TB) (cosmos.Context, Keeper) { authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), ) + dk := distkeeper.NewKeeper( + cdc, + runtime.NewKVStoreService(keydist), + ak, + bk, + sk, + authtypes.FeeCollectorName, + govModuleAddr, + ) + + mk := mintkeeper.NewKeeper( + cdc, + runtime.NewKVStoreService(keyMint), + sk, + ak, + bk, + authtypes.FeeCollectorName, + govModuleAddr, + ) k := NewKVStore( cdc, @@ -134,6 +164,8 @@ func SetupKeeper(t testing.TB) (cosmos.Context, Keeper) { *sk, govModuleAddr, logger, + mk, + dk, ) k.SetVersion(ctx, common.GetCurrentVersion()) @@ -147,10 +179,12 @@ func SetupKeeperWithStaking(t testing.TB) (cosmos.Context, Keeper, stakingkeeper storeKey := storetypes.NewKVStoreKey(types.StoreKey) keyAcc := cosmos.NewKVStoreKey(authtypes.StoreKey) keyBank := cosmos.NewKVStoreKey(banktypes.StoreKey) + keyMint := cosmos.NewKVStoreKey(minttypes.StoreKey) keyStake := cosmos.NewKVStoreKey(stakingtypes.StoreKey) keyParams := cosmos.NewKVStoreKey(typesparams.StoreKey) tkeyParams := cosmos.NewTransientStoreKey(typesparams.TStoreKey) memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) + keydist := cosmos.NewKVStoreKey(disttypes.StoreKey) cfg := sdk.GetConfig() @@ -168,6 +202,7 @@ func SetupKeeperWithStaking(t testing.TB) (cosmos.Context, Keeper, stakingkeeper stateStore.MountStoreWithDB(keyParams, storetypes.StoreTypeIAVL, db) stateStore.MountStoreWithDB(tkeyParams, storetypes.StoreTypeIAVL, db) stateStore.MountStoreWithDB(memStoreKey, storetypes.StoreTypeMemory, nil) + stateStore.MountStoreWithDB(keydist, storetypes.StoreTypeIAVL, db) require.NoError(t, stateStore.LoadLatestVersion()) encodingConfig := arekoappParams.MakeEncodingConfig() @@ -184,20 +219,25 @@ func SetupKeeperWithStaking(t testing.TB) (cosmos.Context, Keeper, stakingkeeper ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger()) - govModuleAddr := "arkeo12jurap3ypfmwzghj9d0t4wanc9gne2cktxh2y2" + govModuleAddr := "tarkeo1krj9ywwmqcellgunxg66kjw5dtt402kq0uf6pu" _ = paramskeeper.NewKeeper(cdc, amino, keyParams, tkeyParams) ak := authkeeper.NewAccountKeeper( cdc, runtime.NewKVStoreService(keyAcc), authtypes.ProtoBaseAccount, map[string][]string{ - stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, - stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, - types.ModuleName: {authtypes.Minter, authtypes.Burner}, - types.ReserveName: {}, - types.ProviderName: {}, - types.ContractName: {}, - govtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + distrtypes.ModuleName: {authtypes.Minter}, + stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, + stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, + types.ModuleName: {authtypes.Minter, authtypes.Burner}, + types.ReserveName: {}, + types.ProviderName: {}, + types.ContractName: {}, + govtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + types.FoundationDevAccount: {authtypes.Minter, authtypes.Burner}, + types.FoundationGrantsAccount: {authtypes.Minter, authtypes.Burner}, + types.FoundationCommunityAccount: {authtypes.Minter, authtypes.Burner}, + minttypes.ModuleName: {authtypes.Minter}, }, authcodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()), sdk.Bech32PrefixAccAddr, @@ -224,6 +264,26 @@ func SetupKeeperWithStaking(t testing.TB) (cosmos.Context, Keeper, stakingkeeper authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), ) + mk := mintkeeper.NewKeeper( + cdc, + runtime.NewKVStoreService(keyMint), + sk, + ak, + bk, + authtypes.FeeCollectorName, + govModuleAddr, + ) + dk := distkeeper.NewKeeper( + cdc, + runtime.NewKVStoreService(keydist), + ak, + bk, + sk, + authtypes.FeeCollectorName, + govModuleAddr, + ) + _ = dk.FeePool.Set(ctx, disttypes.FeePool{CommunityPool: []sdk.DecCoin{sdk.NewDecCoin(configs.Denom, math.NewInt(10000))}}) + k := NewKVStore( cdc, storeKey, @@ -234,6 +294,8 @@ func SetupKeeperWithStaking(t testing.TB) (cosmos.Context, Keeper, stakingkeeper *sk, govModuleAddr, logger, + mk, + dk, ) k.SetVersion(ctx, common.GetCurrentVersion()) diff --git a/x/arkeo/keeper/manager.go b/x/arkeo/keeper/manager.go index 9281f7d4..080ce0c0 100644 --- a/x/arkeo/keeper/manager.go +++ b/x/arkeo/keeper/manager.go @@ -4,8 +4,10 @@ import ( "fmt" "cosmossdk.io/errors" + sdkmath "cosmossdk.io/math" abci "github.com/cometbft/cometbft/abci/types" cmptm "github.com/cometbft/cometbft/proto/tendermint/types" + sdk "github.com/cosmos/cosmos-sdk/types" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/arkeonetwork/arkeo/common" @@ -52,7 +54,35 @@ func (mgr *Manager) BeginBlock(ctx cosmos.Context) error { } votes = append(votes, abciVote) } - if err := mgr.ValidatorPayout(ctx, votes); err != nil { + + // Get the circulating supply after calculating inflation + circSupply, err := mgr.circulatingSupplyAfterInflationCalc(ctx) + if err != nil { + ctx.Logger().Error("unable to get supply with inflation calculation", "error", err) + return err + } + + err = mgr.keeper.MoveTokensFromDistributionToFoundationPoolAccount(ctx) + if err != nil { + ctx.Logger().Error("unable to send tokens from distribution to pool account", "error", err) + } + + validatorPayoutCycle := mgr.FetchConfig(ctx, configs.ValidatorPayoutCycle) + + emissionCurve := mgr.FetchConfig(ctx, configs.EmissionCurve) // Emission curve factor + blocksPerYear := mgr.FetchConfig(ctx, configs.BlocksPerYear) + + // Calculate Block Rewards + blockReward := mgr.calcBlockReward(ctx, circSupply.Amount.ToLegacyDec().RoundInt64(), emissionCurve, blocksPerYear, validatorPayoutCycle) + ctx.Logger().Info(fmt.Sprintf("Block Reward %v", blockReward)) + + // Distribute Minted To Pools + balanceDistribution, err := mgr.keeper.MintAndDistributeTokens(ctx, blockReward) + if err != nil { + ctx.Logger().Error("unable to mint and distribute tokens", "error", err) + } + + if err := mgr.ValidatorPayout(ctx, votes, balanceDistribution); err != nil { ctx.Logger().Error("unable to settle contracts", "error", err) } return nil @@ -186,123 +216,124 @@ func (mgr Manager) ContractEndBlock(ctx cosmos.Context) error { // units = U / (T / t) // Since the development goal at the moment is to get this chain up and // running, we can save this optimization for another day. -func (mgr Manager) ValidatorPayout(ctx cosmos.Context, votes []abci.VoteInfo) error { - valCycle := mgr.FetchConfig(ctx, configs.ValidatorPayoutCycle) - if valCycle == 0 || ctx.BlockHeight()%valCycle != 0 { +func (mgr Manager) ValidatorPayout(ctx cosmos.Context, votes []abci.VoteInfo, blockReward cosmos.Coin) error { + if blockReward.IsZero() { return nil } - emissionCurve := mgr.FetchConfig(ctx, configs.EmissionCurve) - blocksPerYear := mgr.FetchConfig(ctx, configs.BlocksPerYear) - reserveBal := mgr.keeper.GetBalance(ctx, mgr.keeper.GetModuleAccAddress(types.ReserveName)) - for _, bal := range reserveBal { - reserve := bal.Amount - blockReward := mgr.calcBlockReward(reserve.Int64(), emissionCurve, (blocksPerYear / valCycle)) + // sum tokens + total := cosmos.ZeroInt() + for _, vote := range votes { + val, err := mgr.sk.ValidatorByConsAddr(ctx, vote.Validator.Address) + if err != nil { + ctx.Logger().Info("unable to find validator", "validator", string(vote.Validator.Address)) + continue + } + if !val.IsBonded() || val.IsJailed() { + continue + } + total = total.Add(val.GetDelegatorShares().RoundInt()) + } + if total.IsZero() { + return nil + } - if blockReward.IsZero() { + for _, vote := range votes { + if vote.BlockIdFlag.String() != "BLOCK_ID_FLAG_COMMIT" { + ctx.Logger().Info("validator rewards skipped due to lack of signature", "validator", string(vote.Validator.Address)) continue } - // sum tokens - total := cosmos.ZeroInt() - for _, vote := range votes { - val, err := mgr.sk.ValidatorByConsAddr(ctx, vote.Validator.Address) - if err != nil { - ctx.Logger().Info("unable to find validator", "validator", string(vote.Validator.Address)) - continue - } - if !val.IsBonded() || val.IsJailed() { - continue - } - total = total.Add(val.GetDelegatorShares().RoundInt()) + val, err := mgr.sk.ValidatorByConsAddr(ctx, vote.Validator.Address) + if err != nil { + ctx.Logger().Info("unable to find validator", "validator", string(vote.Validator.Address)) + continue } - if total.IsZero() { - return nil + if !val.IsBonded() || val.IsJailed() { + ctx.Logger().Info("validator rewards skipped due to status or jailed", "validator", val.GetOperator()) + continue } - for _, vote := range votes { + valBz, err := mgr.sk.ValidatorAddressCodec().StringToBytes(val.GetOperator()) + if err != nil { + panic(err) + } - if vote.BlockIdFlag.String() == "BLOCK_ID_FLAG_ABSENT" { - ctx.Logger().Info("validator rewards skipped due to lack of signature", "validator", string(vote.Validator.Address)) - continue - } + valVersion := mgr.keeper.GetVersionForAddress(ctx, valBz) + curVersion := mgr.keeper.GetVersion(ctx) + if valVersion < curVersion { + continue + } + acc := cosmos.AccAddress(val.GetOperator()) - val, err := mgr.sk.ValidatorByConsAddr(ctx, vote.Validator.Address) - if err != nil { - ctx.Logger().Info("unable to find validator", "validator", string(vote.Validator.Address)) - continue - } - if !val.IsBonded() || val.IsJailed() { - ctx.Logger().Info("validator rewards skipped due to status or jailed", "validator", val.GetOperator()) - continue - } + totalReward := common.GetSafeShare(val.GetDelegatorShares().RoundInt(), total, blockReward.Amount) + validatorReward := cosmos.ZeroInt() + rateBasisPts := val.GetCommission().MulInt64(100).RoundInt() - valBz, err := mgr.sk.ValidatorAddressCodec().StringToBytes(val.GetOperator()) - if err != nil { - panic(err) - } + delegates, err := mgr.sk.GetValidatorDelegations(ctx, valBz) + if err != nil { + panic(err) + } - valVersion := mgr.keeper.GetVersionForAddress(ctx, valBz) - curVersion := mgr.keeper.GetVersion(ctx) - if valVersion < curVersion { + for _, delegate := range delegates { + delegateAcc, err := cosmos.AccAddressFromBech32(delegate.DelegatorAddress) + if err != nil { + ctx.Logger().Error("unable to fetch delegate address", "delegate", delegate.DelegatorAddress, "error", err) continue } - acc := cosmos.AccAddress(val.GetOperator()) - - totalReward := common.GetSafeShare(val.GetDelegatorShares().RoundInt(), total, blockReward) - validatorReward := cosmos.ZeroInt() - rateBasisPts := val.GetCommission().MulInt64(100).RoundInt() - - delegates, err := mgr.sk.GetValidatorDelegations(ctx, valBz) - if err != nil { - panic(err) + delegateReward := common.GetSafeShare(delegate.GetShares().RoundInt(), val.GetDelegatorShares().RoundInt(), totalReward) + if acc.String() != delegate.DelegatorAddress { + valFee := common.GetSafeShare(rateBasisPts, cosmos.NewInt(configs.MaxBasisPoints), delegateReward) + delegateReward = delegateReward.Sub(valFee) + validatorReward = validatorReward.Add(valFee) } - - for _, delegate := range delegates { - delegateAcc, err := cosmos.AccAddressFromBech32(delegate.DelegatorAddress) - if err != nil { - ctx.Logger().Error("unable to fetch delegate address", "delegate", delegate.DelegatorAddress, "error", err) - continue - } - delegateReward := common.GetSafeShare(delegate.GetShares().RoundInt(), val.GetDelegatorShares().RoundInt(), totalReward) - if acc.String() != delegate.DelegatorAddress { - valFee := common.GetSafeShare(rateBasisPts, cosmos.NewInt(configs.MaxBasisPoints), delegateReward) - delegateReward = delegateReward.Sub(valFee) - validatorReward = validatorReward.Add(valFee) - } - if err := mgr.keeper.SendFromModuleToAccount(ctx, types.ReserveName, delegateAcc, cosmos.NewCoins(cosmos.NewCoin(bal.Denom, delegateReward))); err != nil { - ctx.Logger().Error("unable to pay rewards to delegate", "delegate", delegate.DelegatorAddress, "error", err) - } - ctx.Logger().Info("delegate rewarded", "delegate", delegateAcc.String(), "amount", delegateReward) + if err := mgr.keeper.SendFromModuleToAccount(ctx, types.ModuleName, delegateAcc, cosmos.NewCoins(cosmos.NewCoin(blockReward.Denom, delegateReward))); err != nil { + ctx.Logger().Error("unable to pay rewards to delegate", "delegate", delegate.DelegatorAddress, "error", err) + continue } + ctx.Logger().Info("delegate rewarded", "delegate", delegateAcc.String(), "amount", delegateReward) + } - if !validatorReward.IsZero() { - if err := mgr.keeper.SendFromModuleToAccount(ctx, types.ReserveName, acc, cosmos.NewCoins(cosmos.NewCoin(bal.Denom, validatorReward))); err != nil { - ctx.Logger().Error("unable to pay rewards to validator", "validator", val.GetOperator(), "error", err) - continue - } - ctx.Logger().Info("validator additional rewards", "validator", acc.String(), "amount", validatorReward) + if !validatorReward.IsZero() { + if err := mgr.keeper.SendFromModuleToAccount(ctx, types.ModuleName, acc, cosmos.NewCoins(cosmos.NewCoin(blockReward.Denom, validatorReward))); err != nil { + ctx.Logger().Error("unable to pay rewards to validator", "validator", val.GetOperator(), "error", err) + continue } + ctx.Logger().Info("validator additional rewards", "validator", acc.String(), "amount", validatorReward) + } - if err := mgr.EmitValidatorPayoutEvent(ctx, acc, validatorReward); err != nil { - ctx.Logger().Error("unable to emit validator payout event", "validator", acc.String(), "error", err) - } + if err := mgr.EmitValidatorPayoutEvent(ctx, acc, validatorReward); err != nil { + ctx.Logger().Error("unable to emit validator payout event", "validator", acc.String(), "error", err) } } return nil } -func (mgr Manager) calcBlockReward(totalReserve, emissionCurve, blocksPerYear int64) cosmos.Int { +func (mgr Manager) calcBlockReward(ctx cosmos.Context, totalReserve, emissionCurve, blocksPerYear, validatorPayoutCycle int64) cosmos.Coin { + sdkContext := sdk.UnwrapSDKContext(ctx) + // Block Rewards will take the latest reserve, divide it by the emission // curve factor, then divide by blocks per year if emissionCurve == 0 || blocksPerYear == 0 { - return cosmos.ZeroInt() + sdkContext.Logger().Info("block and emission-curve cannot be zero") + return cosmos.NewCoin(configs.Denom, sdkmath.NewInt(0)) } + + if validatorPayoutCycle == 0 || sdkContext.BlockHeight()%validatorPayoutCycle != 0 { + sdkContext.Logger().Info("validator payout cycle cannot be zero") + return cosmos.NewCoin(configs.Denom, sdkmath.NewInt(0)) + } + trD := cosmos.NewDec(totalReserve) ecD := cosmos.NewDec(emissionCurve) - bpyD := cosmos.NewDec(blocksPerYear) - return trD.Quo(ecD).Quo(bpyD).RoundInt() + bpyD := cosmos.NewDec((blocksPerYear / validatorPayoutCycle)) + + blockReward := trD.Quo(ecD).Quo(bpyD).RoundInt() + + sdkContext.Logger().Info(fmt.Sprintf("block reward %d ", trD.Quo(ecD).Quo(bpyD).TruncateInt64())) + + return cosmos.NewCoin(configs.Denom, blockReward) } func (mgr Manager) FetchConfig(ctx cosmos.Context, name configs.ConfigName) int64 { @@ -398,3 +429,34 @@ func (mgr Manager) contractDebt(ctx cosmos.Context, contract types.Contract) (co return debt, nil } + +func (mgr Manager) circulatingSupplyAfterInflationCalc(ctx cosmos.Context) (cosmos.Coin, error) { + sdkContext := sdk.UnwrapSDKContext(ctx) + + // Get the circulating supply + circulatingSupply, err := mgr.keeper.GetCirculatingSupply(ctx, configs.Denom) + if err != nil { + sdkContext.Logger().Error(fmt.Sprintf("failed to get circulating supply %s", err)) + return cosmos.NewCoin(configs.Denom, sdkmath.NewInt(0)), err + } + + // Get the inflation rate + inflationRate, err := mgr.keeper.GetInflationRate(ctx) + if err != nil { + sdkContext.Logger().Error(fmt.Sprintf("failed to get inflation rate: %s", err)) + return cosmos.NewCoin(configs.Denom, sdkmath.NewInt(0)), err + } + + sdkContext.Logger().Info(fmt.Sprintf("Inflation rate: %v", inflationRate)) + + // Convert circulating supply to decimal for precise calculation + circulatingSupplyDec := sdkmath.LegacyNewDec(circulatingSupply.Amount.Int64()) + + // Multiply circulating supply by inflation rate to get the newly minted token amount + newTokenAmountMintedDec := circulatingSupplyDec.Mul(inflationRate) + + // Convert the result back to integer and truncate any decimals + newTokenAmountMinted := newTokenAmountMintedDec.TruncateInt() + + return cosmos.NewCoin(configs.Denom, newTokenAmountMinted), nil +} diff --git a/x/arkeo/keeper/manager_test.go b/x/arkeo/keeper/manager_test.go index 90d4faf8..a1da1d70 100644 --- a/x/arkeo/keeper/manager_test.go +++ b/x/arkeo/keeper/manager_test.go @@ -3,144 +3,21 @@ package keeper import ( "testing" + abci "github.com/cometbft/cometbft/abci/types" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" + sdk "github.com/cosmos/cosmos-sdk/types" + disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" + sdkmath "cosmossdk.io/math" + "github.com/arkeonetwork/arkeo/common" "github.com/arkeonetwork/arkeo/common/cosmos" "github.com/arkeonetwork/arkeo/x/arkeo/configs" "github.com/arkeonetwork/arkeo/x/arkeo/types" - - abci "github.com/cometbft/cometbft/abci/types" - simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func TestValidatorPayout(t *testing.T) { - ctx, k, sk := SetupKeeperWithStaking(t) - - pks := simtestutil.CreateTestPubKeys(3) - pk1, err := common.NewPubKeyFromCrypto(pks[0]) - require.NoError(t, err) - acc1, err := pk1.GetMyAddress() - require.NoError(t, err) - pk2, err := common.NewPubKeyFromCrypto(pks[1]) - require.NoError(t, err) - acc2, err := pk2.GetMyAddress() - require.NoError(t, err) - pk3, err := common.NewPubKeyFromCrypto(pks[2]) - require.NoError(t, err) - acc3, err := pk3.GetMyAddress() - require.NoError(t, err) - - valAddrs := simtestutil.ConvertAddrsToValAddrs([]cosmos.AccAddress{acc1, acc2, acc3}) - - val1, err := stakingtypes.NewValidator(valAddrs[0].String(), pks[0], stakingtypes.Description{}) - require.NoError(t, err) - val1.Tokens = cosmos.NewInt(100) - val1.DelegatorShares = cosmos.NewDec(100 + 10 + 20) - val1.Status = stakingtypes.Bonded - val1.Commission = stakingtypes.NewCommission(cosmos.NewDecWithPrec(1, 1), cosmos.ZeroDec(), cosmos.ZeroDec()) - - val2, err := stakingtypes.NewValidator(valAddrs[1].String(), pks[1], stakingtypes.Description{}) - require.NoError(t, err) - val2.Tokens = cosmos.NewInt(200) - val2.DelegatorShares = cosmos.NewDec(200 + 20) - val2.Status = stakingtypes.Bonded - val2.Commission = stakingtypes.NewCommission(cosmos.NewDecWithPrec(2, 1), cosmos.ZeroDec(), cosmos.ZeroDec()) - - val3, err := stakingtypes.NewValidator(valAddrs[2].String(), pks[2], stakingtypes.Description{}) - require.NoError(t, err) - val3.Tokens = cosmos.NewInt(500) - val3.DelegatorShares = cosmos.NewDec(500) - val3.Status = stakingtypes.Bonded - val3.Commission = stakingtypes.NewCommission(cosmos.NewDecWithPrec(5, 1), cosmos.ZeroDec(), cosmos.ZeroDec()) - - vals := []stakingtypes.Validator{val1, val2, val3} - for _, val := range vals { - require.NoError(t, sk.SetValidator(ctx, val)) - require.NoError(t, sk.SetValidatorByConsAddr(ctx, val)) - require.NoError(t, sk.SetNewValidatorByPowerIndex(ctx, val)) - } - - delAcc1 := types.GetRandomBech32Addr() - delAcc2 := types.GetRandomBech32Addr() - delAcc3 := types.GetRandomBech32Addr() - - require.NoError(t, sk.SetDelegation(ctx, stakingtypes.NewDelegation(acc1.String(), valAddrs[0].String(), cosmos.NewDec(100)))) - require.NoError(t, sk.SetDelegation(ctx, stakingtypes.NewDelegation(acc2.String(), valAddrs[1].String(), cosmos.NewDec(200)))) - require.NoError(t, sk.SetDelegation(ctx, stakingtypes.NewDelegation(acc3.String(), valAddrs[2].String(), cosmos.NewDec(500)))) - - del1 := stakingtypes.NewDelegation(delAcc1.String(), valAddrs[0].String(), cosmos.NewDec(10)) - del2 := stakingtypes.NewDelegation(delAcc2.String(), valAddrs[1].String(), cosmos.NewDec(20)) - del3 := stakingtypes.NewDelegation(delAcc3.String(), valAddrs[2].String(), cosmos.NewDec(20)) - require.NoError(t, sk.SetDelegation(ctx, del1)) - require.NoError(t, sk.SetDelegation(ctx, del2)) - require.NoError(t, sk.SetDelegation(ctx, del3)) - - // mint token1 - require.NoError(t, k.MintToModule(ctx, types.ModuleName, getCoin(common.Tokens(50000)))) - require.NoError(t, k.SendFromModuleToModule(ctx, types.ModuleName, types.ReserveName, getCoins(common.Tokens(50000)))) - // mint token2 - coins := cosmos.NewCoins(cosmos.NewInt64Coin("tokkie", 50000*1e8)) - require.NoError(t, k.MintToModule(ctx, types.ModuleName, coins[0])) - require.NoError(t, k.SendFromModuleToModule(ctx, types.ModuleName, types.ReserveName, coins)) - - mgr := NewManager(k, sk) - ctx = ctx.WithBlockHeight(mgr.FetchConfig(ctx, configs.ValidatorPayoutCycle)) - - votes := make([]abci.VoteInfo, len(vals)) - for i, val := range vals { - consAddr, err := val.GetConsAddr() - require.NoError(t, err) - votes[i] = abci.VoteInfo{ - Validator: abci.Validator{ - Address: consAddr, - Power: val.Tokens.Int64(), - }, - } - } - - blockReward := int64(158529) - require.NoError(t, mgr.ValidatorPayout(ctx, votes)) - require.Equal(t, k.GetBalanceOfModule(ctx, types.ReserveName, configs.Denom).Int64(), 5000000000000-blockReward) - - // check validator balances - totalBal := cosmos.ZeroInt() - bal := k.GetBalance(ctx, acc1) - require.Equal(t, bal.AmountOf(configs.Denom).Int64(), int64(18632)) - totalBal = totalBal.Add(bal.AmountOf(configs.Denom)) - require.Equal(t, bal.AmountOf("tokkie").Int64(), int64(18632)) - - bal = k.GetBalance(ctx, acc2) - require.Equal(t, bal.AmountOf(configs.Denom).Int64(), int64(37226)) - totalBal = totalBal.Add(bal.AmountOf(configs.Denom)) - require.Equal(t, bal.AmountOf("tokkie").Int64(), int64(37226)) - - bal = k.GetBalance(ctx, acc3) - require.Equal(t, bal.AmountOf(configs.Denom).Int64(), int64(92786)) - totalBal = totalBal.Add(bal.AmountOf(configs.Denom)) - require.Equal(t, bal.AmountOf("tokkie").Int64(), int64(92786)) - - // check delegate balances - bal = k.GetBalance(ctx, delAcc1) - require.Equal(t, bal.AmountOf(configs.Denom).Int64(), int64(1863)) - totalBal = totalBal.Add(bal.AmountOf(configs.Denom)) - require.Equal(t, bal.AmountOf("tokkie").Int64(), int64(1863)) - - bal = k.GetBalance(ctx, delAcc2) - require.Equal(t, bal.AmountOf(configs.Denom).Int64(), int64(3723)) - totalBal = totalBal.Add(bal.AmountOf(configs.Denom)) - require.Equal(t, bal.AmountOf("tokkie").Int64(), int64(3723)) - - bal = k.GetBalance(ctx, delAcc3) - require.Equal(t, bal.AmountOf(configs.Denom).Int64(), int64(3711)) - _ = totalBal.Add(bal.AmountOf(configs.Denom)) - require.Equal(t, bal.AmountOf("tokkie").Int64(), int64(3711)) - - // ensure block reward is equal to total rewarded to validators and delegates - require.Equal(t, blockReward, int64(158529)) -} - func TestContractEndBlock(t *testing.T) { ctx, k, sk := SetupKeeperWithStaking(t) ctx = ctx.WithBlockHeight(10) @@ -404,3 +281,195 @@ func TestInvariantMaxSupply(t *testing.T) { require.NoError(t, k.MintToModule(ctx, types.ModuleName, getCoin(200_000_000*1e8))) require.ErrorIs(t, mgr.invariantMaxSupply(ctx), types.ErrInvariantMaxSupply) } + +func TestParamsRewardsPercentage(t *testing.T) { + ctx, k, _ := SetupKeeperWithStaking(t) + + params := k.GetParams(ctx) + + require.Equal(t, params.CommunityPoolPercentage.Int64(), int64(10)) +} +func TestCommunityPoolDistributionToFoundationCommunityPool(t *testing.T) { + ctx, k, sk := SetupKeeperWithStaking(t) + mgr := NewManager(k, sk) + + require.NoError(t, k.MintToModule(ctx, disttypes.ModuleName, getCoin(common.Tokens(200000)))) + + err := mgr.keeper.MoveTokensFromDistributionToFoundationPoolAccount(ctx) + require.NoError(t, err) + + address, err := sdk.AccAddressFromBech32(types.FoundationCommunityAccount) + require.NoError(t, err) + + bal := mgr.keeper.GetBalance(ctx, address).AmountOf(configs.Denom) + + require.Equal(t, bal, sdkmath.NewInt(10000)) +} + +func TestBlockRewardCalculation(t *testing.T) { + ctx, k, sk := SetupKeeperWithStaking(t) + mgr := NewManager(k, sk) + + // BlockPer Year -> 5000 + // Emission Curve -> 10 + // Total Reserve -> 100000000 + // validator cycle -> 100 + // reward = (totalReserve / emissionCurve) / (blocksPerYear / valCycle)) -> 2000 + valCycle := int64(100) + emissionCurve := int64(10) + blocksPerYear := int64(5000) + totalReserve := int64(1000000) + + reward := mgr.calcBlockReward(ctx, totalReserve, emissionCurve, blocksPerYear, valCycle) + + require.Equal(t, reward.Amount.Int64(), int64(2000)) + + valCycle = int64(10) + emissionCurve = int64(5) + blocksPerYear = int64(200) + totalReserve = int64(999999) + + reward = mgr.calcBlockReward(ctx, totalReserve, emissionCurve, blocksPerYear, valCycle) + + require.Equal(t, reward.Amount.Int64(), int64(10000)) // its 9999.99 rounded to 10000 +} + +func TestValidatorPayouts(t *testing.T) { + ctx, k, sk := SetupKeeperWithStaking(t) + mgr := NewManager(k, sk) + + valCycle := int64(100) + emissionCurve := int64(10) + blocksPerYear := int64(5000) + totalReserve := int64(1000000000) + + blockReward := mgr.calcBlockReward(ctx, totalReserve, emissionCurve, blocksPerYear, valCycle) + + require.Equal(t, blockReward.Amount.Int64(), int64(2000000)) + + pks := simtestutil.CreateTestPubKeys(3) + pk1, err := common.NewPubKeyFromCrypto(pks[0]) + require.NoError(t, err) + acc1, err := pk1.GetMyAddress() + require.NoError(t, err) + pk2, err := common.NewPubKeyFromCrypto(pks[1]) + require.NoError(t, err) + acc2, err := pk2.GetMyAddress() + require.NoError(t, err) + pk3, err := common.NewPubKeyFromCrypto(pks[2]) + require.NoError(t, err) + acc3, err := pk3.GetMyAddress() + require.NoError(t, err) + + valAddrs := simtestutil.ConvertAddrsToValAddrs([]cosmos.AccAddress{acc1, acc2, acc3}) + + val1, err := stakingtypes.NewValidator(valAddrs[0].String(), pks[0], stakingtypes.Description{}) + require.NoError(t, err) + val1.Tokens = cosmos.NewInt(100) + val1.DelegatorShares = cosmos.NewDec(130) // Validator + Delegations + val1.Status = stakingtypes.Bonded + val1.Commission = stakingtypes.NewCommission(cosmos.NewDecWithPrec(1, 1), cosmos.ZeroDec(), cosmos.ZeroDec()) + + val2, err := stakingtypes.NewValidator(valAddrs[1].String(), pks[1], stakingtypes.Description{}) + require.NoError(t, err) + val2.Tokens = cosmos.NewInt(200) + val2.DelegatorShares = cosmos.NewDec(220) + val2.Status = stakingtypes.Bonded + val2.Commission = stakingtypes.NewCommission(cosmos.NewDecWithPrec(2, 1), cosmos.ZeroDec(), cosmos.ZeroDec()) + + val3, err := stakingtypes.NewValidator(valAddrs[2].String(), pks[2], stakingtypes.Description{}) + require.NoError(t, err) + val3.Tokens = cosmos.NewInt(500) + val3.DelegatorShares = cosmos.NewDec(500) + val3.Status = stakingtypes.Bonded + val3.Commission = stakingtypes.NewCommission(cosmos.NewDecWithPrec(5, 1), cosmos.ZeroDec(), cosmos.ZeroDec()) + + vals := []stakingtypes.Validator{val1, val2, val3} + for _, val := range vals { + require.NoError(t, sk.SetValidator(ctx, val)) + require.NoError(t, sk.SetValidatorByConsAddr(ctx, val)) + require.NoError(t, sk.SetNewValidatorByPowerIndex(ctx, val)) + } + + delAcc1 := types.GetRandomBech32Addr() + delAcc2 := types.GetRandomBech32Addr() + delAcc3 := types.GetRandomBech32Addr() + + require.NoError(t, sk.SetDelegation(ctx, stakingtypes.NewDelegation(acc1.String(), valAddrs[0].String(), cosmos.NewDec(100)))) + require.NoError(t, sk.SetDelegation(ctx, stakingtypes.NewDelegation(acc2.String(), valAddrs[1].String(), cosmos.NewDec(200)))) + require.NoError(t, sk.SetDelegation(ctx, stakingtypes.NewDelegation(acc3.String(), valAddrs[2].String(), cosmos.NewDec(500)))) + + del1 := stakingtypes.NewDelegation(delAcc1.String(), valAddrs[0].String(), cosmos.NewDec(10)) + del2 := stakingtypes.NewDelegation(delAcc2.String(), valAddrs[1].String(), cosmos.NewDec(20)) + del3 := stakingtypes.NewDelegation(delAcc3.String(), valAddrs[2].String(), cosmos.NewDec(20)) + require.NoError(t, sk.SetDelegation(ctx, del1)) + require.NoError(t, sk.SetDelegation(ctx, del2)) + require.NoError(t, sk.SetDelegation(ctx, del3)) + + // Mint initial funds to the reserve + require.NoError(t, k.MintToModule(ctx, types.ModuleName, getCoin(common.Tokens(200000)))) + + ctx = ctx.WithBlockHeight(mgr.FetchConfig(ctx, configs.ValidatorPayoutCycle)) + + // Create VoteInfo for each validator + votes := make([]abci.VoteInfo, len(vals)) + for i, val := range vals { + consAddr, err := val.GetConsAddr() + require.NoError(t, err) + votes[i] = abci.VoteInfo{ + Validator: abci.Validator{ + Address: consAddr, + Power: val.Tokens.Int64(), + }, + BlockIdFlag: 2, + } + } + balanceDistribution, err := mgr.keeper.MintAndDistributeTokens(ctx, blockReward) + if err != nil { + ctx.Logger().Error("unable to mint and distribute tokens", "error", err) + } + devAccountAddress, err := sdk.AccAddressFromBech32(types.FoundationDevAccount) + require.NoError(t, err) + + grantAccountAddress, err := sdk.AccAddressFromBech32(types.FoundationGrantsAccount) + require.NoError(t, err) + + communityAccountAddress, err := sdk.AccAddressFromBech32(types.FoundationCommunityAccount) + require.NoError(t, err) + + devAccountBal := k.GetBalance(ctx, devAccountAddress).AmountOf(configs.Denom) + require.Equal(t, devAccountBal, sdkmath.NewInt(400000)) + + grantAccountBal := k.GetBalance(ctx, grantAccountAddress).AmountOf(configs.Denom) + require.Equal(t, grantAccountBal, sdkmath.NewInt(400000)) + + communityAccountBal := k.GetBalance(ctx, communityAccountAddress).AmountOf(configs.Denom) + require.Equal(t, communityAccountBal, sdkmath.NewInt(200000)) + + moduleBalance := k.GetBalanceOfModule(ctx, types.ModuleName, configs.Denom) + require.Equal(t, moduleBalance.Int64(), int64(20000001000000)) + + require.NoError(t, mgr.ValidatorPayout(ctx, votes, balanceDistribution)) + + totalBal := cosmos.ZeroInt() + + // Check balances of validators 7 + checkBalance(ctx, t, k, acc1, configs.Denom, 117529, &totalBal) + checkBalance(ctx, t, k, acc2, configs.Denom, 234824, &totalBal) + checkBalance(ctx, t, k, acc3, configs.Denom, 585294, &totalBal) + + // Check balances of delegates + checkBalance(ctx, t, k, delAcc1, configs.Denom, 11753, &totalBal) + checkBalance(ctx, t, k, delAcc2, configs.Denom, 23482, &totalBal) + checkBalance(ctx, t, k, delAcc3, configs.Denom, 23411, &totalBal) + + require.Equal(t, totalBal.ToLegacyDec(), sdkmath.LegacyNewDec(996293)) + + moduleBalance = k.GetBalanceOfModule(ctx, types.ModuleName, configs.Denom) + require.Equal(t, moduleBalance.Int64(), int64(20000000000000)) +} +func checkBalance(ctx cosmos.Context, t *testing.T, k Keeper, acc cosmos.AccAddress, denom string, expectedAmt int64, total *sdkmath.Int) { + bal := k.GetBalance(ctx, acc) + *total = total.Add(bal.AmountOf(denom)) + require.Equal(t, bal.AmountOf(denom).Int64(), expectedAmt) +} diff --git a/x/arkeo/module.go b/x/arkeo/module.go index 24735f37..23c46751 100644 --- a/x/arkeo/module.go +++ b/x/arkeo/module.go @@ -5,6 +5,8 @@ import ( "encoding/json" "fmt" + "cosmossdk.io/core/appmodule" + "github.com/arkeonetwork/arkeo/x/arkeo/client/cli" "github.com/arkeonetwork/arkeo/x/arkeo/keeper" "github.com/arkeonetwork/arkeo/x/arkeo/types" @@ -29,6 +31,7 @@ var ( _ module.AppModuleBasic = AppModuleBasic{} _ module.HasABCIEndBlock = AppModule{} _ module.HasGenesis = AppModule{} + _ appmodule.AppModule = AppModule{} ) // ---------------------------------------------------------------------------- @@ -148,11 +151,14 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw func (am AppModule) ConsensusVersion() uint64 { return 1 } // BeginBlock contains the logic that is automatically triggered at the beginning of each block -func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestFinalizeBlock) { +func (am AppModule) BeginBlock(ctx context.Context) error { + context := sdk.UnwrapSDKContext(ctx) mgr := keeper.NewManager(am.keeper, am.stakingKeeper) - if err := mgr.BeginBlock(ctx); err != nil { - ctx.Logger().Error("manager beginblock error ", "error", err) + if err := mgr.BeginBlock(context); err != nil { + context.Logger().Error("manager beginblock error ", "error", err) + return err } + return nil } // EndBlock contains the logic that is automatically triggered at the end of each block diff --git a/x/arkeo/types/expected_keepers.go b/x/arkeo/types/expected_keepers.go index bf166837..d017c0e7 100644 --- a/x/arkeo/types/expected_keepers.go +++ b/x/arkeo/types/expected_keepers.go @@ -9,6 +9,7 @@ import ( // AccountKeeper defines the expected account keeper used for simulations (noalias) type AccountKeeper interface { GetAccount(ctx context.Context, addr sdk.AccAddress) sdk.AccountI + GetModuleAccount(ctx context.Context, name string) sdk.ModuleAccountI // Methods imported from account should be defined here } diff --git a/x/arkeo/types/keys.go b/x/arkeo/types/keys.go index 0854c3a7..019d4064 100644 --- a/x/arkeo/types/keys.go +++ b/x/arkeo/types/keys.go @@ -20,3 +20,10 @@ const ( func KeyPrefix(p string) []byte { return []byte(p) } + +// Foundational Accounts +const ( + FoundationDevAccount = "tarkeo10sav33v67743s6cl2cvjmmua7c5arysw3txz9r" + FoundationCommunityAccount = "tarkeo1v50hrsxx0mxar4653aujcnqyjft07w0npcxrjx" + FoundationGrantsAccount = "tarkeo16k3k0erkwaanqnup20dxxenpd6wh058nh4pgup" +) diff --git a/x/arkeo/types/params.go b/x/arkeo/types/params.go index 357196ad..ebfb1a91 100644 --- a/x/arkeo/types/params.go +++ b/x/arkeo/types/params.go @@ -1,6 +1,7 @@ package types import ( + "cosmossdk.io/math" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" "gopkg.in/yaml.v2" ) @@ -14,7 +15,11 @@ func ParamKeyTable() paramtypes.KeyTable { // NewParams creates a new Params instance func NewParams() Params { - return Params{} + return Params{ + CommunityPoolPercentage: math.NewInt(10), + DevFundPercentage: math.NewInt(20), + GrantFundPercentage: math.NewInt(20), + } } // DefaultParams returns a default set of parameters diff --git a/x/arkeo/types/params.pb.go b/x/arkeo/types/params.pb.go index 20b07c81..7bff56db 100644 --- a/x/arkeo/types/params.pb.go +++ b/x/arkeo/types/params.pb.go @@ -5,7 +5,10 @@ package types import ( + cosmossdk_io_math "cosmossdk.io/math" fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + _ "github.com/cosmos/cosmos-sdk/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" @@ -26,6 +29,9 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // Params defines the parameters for the module. type Params struct { + CommunityPoolPercentage cosmossdk_io_math.Int `protobuf:"bytes,1,opt,name=CommunityPoolPercentage,proto3,customtype=cosmossdk.io/math.Int" json:"CommunityPoolPercentage"` + DevFundPercentage cosmossdk_io_math.Int `protobuf:"bytes,2,opt,name=DevFundPercentage,proto3,customtype=cosmossdk.io/math.Int" json:"DevFundPercentage"` + GrantFundPercentage cosmossdk_io_math.Int `protobuf:"bytes,3,opt,name=GrantFundPercentage,proto3,customtype=cosmossdk.io/math.Int" json:"GrantFundPercentage"` } func (m *Params) Reset() { *m = Params{} } @@ -67,16 +73,26 @@ func init() { func init() { proto.RegisterFile("arkeo/arkeo/params.proto", fileDescriptor_47c871f4fc73dfc5) } var fileDescriptor_47c871f4fc73dfc5 = []byte{ - // 142 bytes of a gzipped FileDescriptorProto + // 290 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x48, 0x2c, 0xca, 0x4e, 0xcd, 0xd7, 0x87, 0x90, 0x05, 0x89, 0x45, 0x89, 0xb9, 0xc5, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0xdc, 0x60, 0x31, 0x3d, 0x30, 0x29, 0x25, 0x92, 0x9e, 0x9f, 0x9e, 0x0f, 0x16, 0xd7, 0x07, - 0xb1, 0x20, 0x4a, 0x94, 0xf8, 0xb8, 0xd8, 0x02, 0xc0, 0x5a, 0xac, 0x58, 0x66, 0x2c, 0x90, 0x67, - 0x70, 0x72, 0x3d, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, - 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0xed, 0xf4, 0xcc, - 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0x88, 0x5d, 0x79, 0xa9, 0x25, 0xe5, 0xf9, 0x45, - 0xd9, 0x50, 0x8b, 0x2b, 0xa0, 0x74, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0x74, 0x63, - 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x93, 0xe1, 0x2d, 0xa8, 0x9c, 0x00, 0x00, 0x00, + 0xb1, 0x20, 0x4a, 0xa4, 0xe4, 0x92, 0xf3, 0x8b, 0x73, 0xf3, 0x8b, 0xf5, 0x93, 0x12, 0x8b, 0x53, + 0xf5, 0xcb, 0x0c, 0x93, 0x52, 0x4b, 0x12, 0x0d, 0xf5, 0x93, 0xf3, 0x33, 0xf3, 0xa0, 0xf2, 0x92, + 0x10, 0xf9, 0x78, 0x88, 0x46, 0x08, 0x07, 0x22, 0xa5, 0xb4, 0x9e, 0x89, 0x8b, 0x2d, 0x00, 0x6c, + 0x9d, 0x50, 0x2a, 0x97, 0xb8, 0x73, 0x7e, 0x6e, 0x6e, 0x69, 0x5e, 0x66, 0x49, 0x65, 0x40, 0x7e, + 0x7e, 0x4e, 0x40, 0x6a, 0x51, 0x72, 0x6a, 0x5e, 0x49, 0x62, 0x7a, 0xaa, 0x04, 0xa3, 0x02, 0xa3, + 0x06, 0xa7, 0x93, 0xf6, 0x89, 0x7b, 0xf2, 0x0c, 0xb7, 0xee, 0xc9, 0x8b, 0x42, 0x4c, 0x28, 0x4e, + 0xc9, 0xd6, 0xcb, 0xcc, 0xd7, 0xcf, 0x4d, 0x2c, 0xc9, 0xd0, 0xf3, 0xcc, 0x2b, 0xb9, 0xb4, 0x45, + 0x97, 0x0b, 0x6a, 0xb4, 0x67, 0x5e, 0x49, 0x10, 0x2e, 0xb3, 0x84, 0x22, 0xb9, 0x04, 0x5d, 0x52, + 0xcb, 0xdc, 0x4a, 0xf3, 0x52, 0x90, 0x2c, 0x60, 0x22, 0xdd, 0x02, 0x4c, 0x53, 0x84, 0x62, 0xb9, + 0x84, 0xdd, 0x8b, 0x12, 0xf3, 0x4a, 0xd0, 0x0c, 0x67, 0x26, 0xdd, 0x70, 0x6c, 0xe6, 0x58, 0xb1, + 0xcc, 0x58, 0x20, 0xcf, 0xe0, 0xe4, 0x7a, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, + 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, + 0x51, 0xda, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0x90, 0x88, 0xcc, 0x4b, + 0x2d, 0x29, 0xcf, 0x2f, 0xca, 0x86, 0xc6, 0x6a, 0x05, 0x94, 0x2e, 0xa9, 0x2c, 0x48, 0x2d, 0x4e, + 0x62, 0x03, 0x87, 0xbf, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0xdb, 0xf8, 0x23, 0xd7, 0xf9, 0x01, + 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -99,6 +115,36 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size := m.GrantFundPercentage.Size() + i -= size + if _, err := m.GrantFundPercentage.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size := m.DevFundPercentage.Size() + i -= size + if _, err := m.DevFundPercentage.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size := m.CommunityPoolPercentage.Size() + i -= size + if _, err := m.CommunityPoolPercentage.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa return len(dAtA) - i, nil } @@ -119,6 +165,12 @@ func (m *Params) Size() (n int) { } var l int _ = l + l = m.CommunityPoolPercentage.Size() + n += 1 + l + sovParams(uint64(l)) + l = m.DevFundPercentage.Size() + n += 1 + l + sovParams(uint64(l)) + l = m.GrantFundPercentage.Size() + n += 1 + l + sovParams(uint64(l)) return n } @@ -157,6 +209,108 @@ func (m *Params) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CommunityPoolPercentage", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + 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 ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.CommunityPoolPercentage.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DevFundPercentage", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + 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 ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.DevFundPercentage.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GrantFundPercentage", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + 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 ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.GrantFundPercentage.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipParams(dAtA[iNdEx:]) diff --git a/x/arkeo/types/query.pb.gw.go b/x/arkeo/types/query.pb.gw.go index fc8cce66..747f7ebe 100644 --- a/x/arkeo/types/query.pb.gw.go +++ b/x/arkeo/types/query.pb.gw.go @@ -1,6 +1,4 @@ // DONTCOVER -// DONTCOVER -// DONTCOVER // Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. // source: arkeo/arkeo/query.proto diff --git a/x/claim/types/query.pb.gw.go b/x/claim/types/query.pb.gw.go index 33cf14da..95ff1fc6 100644 --- a/x/claim/types/query.pb.gw.go +++ b/x/claim/types/query.pb.gw.go @@ -1,6 +1,4 @@ // DONTCOVER -// DONTCOVER -// DONTCOVER // Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. // source: arkeo/claim/query.proto diff --git a/x/claim/types/tx.pb.go b/x/claim/types/tx.pb.go index 59b8408d..ee63e8ac 100644 --- a/x/claim/types/tx.pb.go +++ b/x/claim/types/tx.pb.go @@ -512,45 +512,45 @@ func init() { func init() { proto.RegisterFile("arkeo/claim/tx.proto", fileDescriptor_6a4ddac60cb43154) } var fileDescriptor_6a4ddac60cb43154 = []byte{ - // 602 bytes of a gzipped FileDescriptorProto + // 607 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x54, 0xbf, 0x6f, 0xd3, 0x40, - 0x14, 0xae, 0x09, 0xfd, 0xf5, 0xd2, 0x56, 0xd4, 0xb4, 0xd4, 0x71, 0xa9, 0x09, 0x96, 0x40, 0x51, - 0x80, 0x58, 0x04, 0x89, 0x21, 0x5b, 0x5a, 0xb5, 0x13, 0x59, 0x42, 0x91, 0x10, 0x4b, 0xe4, 0x3a, - 0x57, 0xdb, 0x2a, 0xf6, 0x85, 0xbb, 0x0b, 0x94, 0x0d, 0x31, 0x32, 0xb1, 0x31, 0xf0, 0x2f, 0x20, - 0x91, 0x81, 0x3f, 0x02, 0xb6, 0x8a, 0x89, 0x11, 0x25, 0x43, 0xfe, 0x0d, 0xe4, 0x3b, 0x9f, 0x6b, - 0x3b, 0x69, 0x84, 0xb2, 0x5c, 0xf2, 0xbe, 0xef, 0xbd, 0x97, 0xef, 0xbb, 0x7b, 0x2f, 0xb0, 0x65, - 0x93, 0x33, 0x84, 0x2d, 0xe7, 0xb5, 0xed, 0x07, 0x16, 0x3b, 0xaf, 0xf5, 0x08, 0x66, 0x58, 0x2d, - 0x72, 0xb4, 0xc6, 0x51, 0xbd, 0xe4, 0x60, 0x1a, 0x60, 0xda, 0xe1, 0x94, 0x25, 0x02, 0x91, 0xa7, - 0x1b, 0xe9, 0x6a, 0x7e, 0x76, 0x08, 0x72, 0x30, 0xe9, 0xc6, 0xfc, 0x96, 0x8b, 0x5d, 0x2c, 0xea, - 0xa2, 0x6f, 0x31, 0xba, 0x23, 0x7a, 0x58, 0x01, 0x75, 0xad, 0xb7, 0x8f, 0xa3, 0x8f, 0x98, 0xd8, - 0xb4, 0x03, 0x3f, 0xc4, 0x16, 0x3f, 0x05, 0x64, 0x7e, 0x53, 0xa0, 0xd8, 0xa2, 0xee, 0x41, 0xd4, - 0xfb, 0x90, 0x79, 0x6a, 0x1d, 0x96, 0x1d, 0x82, 0x6c, 0x86, 0x89, 0xa6, 0x94, 0x95, 0xca, 0xea, - 0xbe, 0xf6, 0xfb, 0xc7, 0xa3, 0xad, 0x58, 0x54, 0xb3, 0xdb, 0x25, 0x88, 0xd2, 0xe7, 0x8c, 0xf8, - 0xa1, 0xdb, 0x96, 0x89, 0xea, 0x1d, 0x28, 0x22, 0xe6, 0x75, 0x6c, 0xc1, 0x6a, 0xd7, 0xa2, 0xba, - 0x36, 0x20, 0xe6, 0xc5, 0xf9, 0xea, 0x6d, 0x58, 0xa5, 0xbe, 0x1b, 0xda, 0xac, 0x4f, 0x90, 0x56, - 0xe0, 0xf4, 0x25, 0xd0, 0xa8, 0x7e, 0x1c, 0x0f, 0xaa, 0xb2, 0xd9, 0xa7, 0xf1, 0xa0, 0x5a, 0x12, - 0xae, 0xcf, 0x63, 0xdf, 0x29, 0x79, 0xe6, 0x36, 0xdc, 0x4c, 0x85, 0x6d, 0x44, 0x7b, 0x38, 0xa4, - 0xc8, 0x7c, 0x03, 0xeb, 0x12, 0x6e, 0x46, 0xb5, 0xf3, 0xd8, 0x68, 0x3c, 0xcc, 0xeb, 0xd8, 0x9d, - 0xae, 0x83, 0xff, 0x82, 0xb9, 0x03, 0xdb, 0x19, 0x20, 0xd1, 0xf2, 0x5d, 0x81, 0x1b, 0x2d, 0xea, - 0x1e, 0x13, 0x3b, 0xa4, 0xa7, 0x88, 0xf0, 0x8c, 0xb9, 0xae, 0xf5, 0x29, 0xac, 0x32, 0xdc, 0x4c, - 0x5f, 0xea, 0x8c, 0xaa, 0xcb, 0xd4, 0x86, 0x95, 0xf7, 0x61, 0x4c, 0xf8, 0xc8, 0x88, 0x33, 0x75, - 0xd0, 0xf2, 0x58, 0xe2, 0xe6, 0x97, 0x98, 0x8f, 0x66, 0xb7, 0x3b, 0xbf, 0x91, 0x0a, 0x2c, 0x3a, - 0x9e, 0xed, 0x87, 0xdc, 0xc4, 0x46, 0x5d, 0xad, 0xa5, 0xa6, 0xbf, 0x76, 0x10, 0x31, 0x6d, 0x91, - 0xa0, 0x6a, 0xb0, 0x2c, 0xa7, 0x48, 0x8c, 0x89, 0x0c, 0xd5, 0x5b, 0xb0, 0x64, 0x07, 0xb8, 0x1f, - 0x32, 0xed, 0x7a, 0x59, 0xa9, 0x14, 0xda, 0x71, 0xf4, 0x3f, 0xc3, 0x23, 0xb5, 0xc7, 0xc3, 0x23, - 0xc3, 0xc4, 0xe2, 0x17, 0x05, 0x36, 0xe5, 0x53, 0x1e, 0x7b, 0x98, 0x08, 0x29, 0xf3, 0x18, 0xbd, - 0x0b, 0x6b, 0xa7, 0x04, 0x07, 0xb9, 0x4d, 0x28, 0x46, 0x98, 0x5c, 0x85, 0x3d, 0x00, 0x86, 0x3b, - 0x59, 0x93, 0xa9, 0xb7, 0x5b, 0x4b, 0xdb, 0x31, 0x77, 0xa1, 0x34, 0x21, 0x4c, 0xca, 0xae, 0x7f, - 0x2d, 0x40, 0xa1, 0x45, 0x5d, 0xf5, 0x08, 0x56, 0x92, 0xed, 0xd5, 0x32, 0x57, 0x9b, 0xda, 0x14, - 0xbd, 0x7c, 0x15, 0x23, 0xfb, 0xa9, 0xcf, 0x00, 0x52, 0x0b, 0xa4, 0x4f, 0xcd, 0xe7, 0x9c, 0x6e, - 0x5e, 0xcd, 0x25, 0xdd, 0x5e, 0xc0, 0x7a, 0x76, 0x03, 0xf6, 0xf2, 0x45, 0x19, 0x5a, 0xbf, 0x37, - 0x93, 0x4e, 0xda, 0x1e, 0xc1, 0x4a, 0x32, 0x8a, 0x13, 0x66, 0x25, 0x33, 0x69, 0x36, 0xff, 0xe6, - 0xea, 0x4b, 0xd8, 0xc8, 0xbd, 0xb7, 0x31, 0xd5, 0x54, 0xc2, 0xeb, 0xf7, 0x67, 0xf3, 0xb2, 0xb3, - 0xbe, 0xf8, 0x61, 0x3c, 0xa8, 0x2a, 0xfb, 0x87, 0x3f, 0x87, 0x86, 0x72, 0x31, 0x34, 0x94, 0xbf, - 0x43, 0x43, 0xf9, 0x3c, 0x32, 0x16, 0x2e, 0x46, 0xc6, 0xc2, 0x9f, 0x91, 0xb1, 0xf0, 0xea, 0x81, - 0xeb, 0x33, 0xaf, 0x7f, 0x52, 0x73, 0x70, 0x60, 0xf1, 0x96, 0x21, 0x62, 0xef, 0x30, 0x39, 0xb3, - 0xb2, 0x83, 0xcb, 0xde, 0xf7, 0x10, 0x3d, 0x59, 0xe2, 0xff, 0xd2, 0x4f, 0xfe, 0x05, 0x00, 0x00, - 0xff, 0xff, 0x10, 0xa2, 0x81, 0xc3, 0x47, 0x06, 0x00, 0x00, + 0x14, 0x8e, 0x09, 0xfd, 0x91, 0x17, 0x5a, 0x51, 0x93, 0x52, 0xc7, 0xa5, 0x6e, 0xb0, 0x04, 0x8a, + 0x02, 0xc4, 0x10, 0x24, 0x86, 0x6c, 0x69, 0xd5, 0x4e, 0x64, 0x09, 0x45, 0x42, 0x2c, 0x91, 0xeb, + 0x5c, 0x6d, 0xab, 0xd8, 0x17, 0xee, 0x2e, 0x50, 0x36, 0xc4, 0xc8, 0xc4, 0xce, 0xbf, 0x80, 0x44, + 0x06, 0x36, 0xfe, 0x01, 0xd8, 0x2a, 0x26, 0x46, 0x94, 0x0c, 0xf9, 0x37, 0x90, 0xcf, 0x3e, 0xd7, + 0x76, 0xd2, 0xa8, 0xca, 0xe2, 0xe4, 0xbe, 0xef, 0xbd, 0x97, 0xef, 0x3b, 0x7f, 0x2f, 0x50, 0x32, + 0xc9, 0x29, 0xc2, 0x86, 0xf5, 0xc6, 0x74, 0x3d, 0x83, 0x9d, 0xd5, 0xfb, 0x04, 0x33, 0x2c, 0x17, + 0x39, 0x5a, 0xe7, 0xa8, 0x5a, 0xb6, 0x30, 0xf5, 0x30, 0xed, 0x72, 0xca, 0x08, 0x0f, 0x61, 0x9d, + 0xaa, 0x25, 0xbb, 0xf9, 0xb3, 0x4b, 0x90, 0x85, 0x49, 0x2f, 0xe2, 0x4b, 0x36, 0xb6, 0x71, 0xd8, + 0x17, 0x7c, 0x8b, 0xd0, 0xad, 0x70, 0x86, 0xe1, 0x51, 0xdb, 0x78, 0xf7, 0x24, 0xf8, 0x88, 0x88, + 0x0d, 0xd3, 0x73, 0x7d, 0x6c, 0xf0, 0x67, 0x08, 0xe9, 0xdf, 0x24, 0x28, 0xb6, 0xa9, 0xbd, 0x1f, + 0xcc, 0x3e, 0x60, 0x8e, 0xdc, 0x80, 0x15, 0x8b, 0x20, 0x93, 0x61, 0xa2, 0x48, 0x15, 0xa9, 0x5a, + 0xd8, 0x53, 0xfe, 0xfc, 0x78, 0x54, 0x8a, 0x44, 0xb5, 0x7a, 0x3d, 0x82, 0x28, 0x7d, 0xc1, 0x88, + 0xeb, 0xdb, 0x1d, 0x51, 0x28, 0xef, 0x42, 0x11, 0x31, 0xa7, 0x6b, 0x86, 0xac, 0x72, 0x2d, 0xe8, + 0xeb, 0x00, 0x62, 0x4e, 0x54, 0x2f, 0xdf, 0x81, 0x02, 0x75, 0x6d, 0xdf, 0x64, 0x03, 0x82, 0x94, + 0x3c, 0xa7, 0x2f, 0x80, 0x66, 0xed, 0xd3, 0x64, 0x58, 0x13, 0xc3, 0x3e, 0x4f, 0x86, 0xb5, 0x72, + 0xe8, 0xfa, 0x2c, 0xf2, 0x9d, 0x90, 0xa7, 0x6f, 0xc2, 0xad, 0xc4, 0xb1, 0x83, 0x68, 0x1f, 0xfb, + 0x14, 0xe9, 0x6f, 0x61, 0x4d, 0xc0, 0xad, 0xa0, 0x77, 0x11, 0x1b, 0xcd, 0x87, 0x59, 0x1d, 0xdb, + 0xb3, 0x75, 0xf0, 0x5f, 0xd0, 0xb7, 0x60, 0x33, 0x05, 0xc4, 0x5a, 0xbe, 0x4b, 0x70, 0xb3, 0x4d, + 0xed, 0x23, 0x62, 0xfa, 0xf4, 0x04, 0x11, 0x5e, 0xb1, 0xd0, 0xb5, 0x3e, 0x83, 0x02, 0xc3, 0xad, + 0xe4, 0xa5, 0xce, 0xe9, 0xba, 0x28, 0x6d, 0x1a, 0x59, 0x1f, 0xda, 0x94, 0x8f, 0x94, 0x38, 0x5d, + 0x05, 0x25, 0x8b, 0xc5, 0x6e, 0x7e, 0x87, 0xf9, 0x68, 0xf5, 0x7a, 0x8b, 0x1b, 0xa9, 0xc2, 0x92, + 0xe5, 0x98, 0xae, 0xcf, 0x4d, 0xac, 0x37, 0xe4, 0x7a, 0x22, 0xfd, 0xf5, 0xfd, 0x80, 0xe9, 0x84, + 0x05, 0xb2, 0x02, 0x2b, 0x22, 0x45, 0x61, 0x4c, 0xc4, 0x51, 0xbe, 0x0d, 0xcb, 0xa6, 0x87, 0x07, + 0x3e, 0x53, 0xae, 0x57, 0xa4, 0x6a, 0xbe, 0x13, 0x9d, 0xae, 0x12, 0x1e, 0xa1, 0x3d, 0x0a, 0x8f, + 0x38, 0xc6, 0x16, 0x7f, 0x4a, 0xb0, 0x21, 0x5e, 0xe5, 0x91, 0x83, 0x49, 0x28, 0x65, 0x11, 0xa3, + 0x77, 0xe1, 0xc6, 0x09, 0xc1, 0x5e, 0x66, 0x13, 0x8a, 0x01, 0x26, 0x56, 0x61, 0x07, 0x80, 0xe1, + 0x6e, 0xda, 0x64, 0xe2, 0xdd, 0x3d, 0xce, 0xda, 0xd9, 0x9d, 0x9d, 0xc1, 0x58, 0xa7, 0xbe, 0x0d, + 0xe5, 0x29, 0x50, 0x58, 0x6b, 0x7c, 0xcd, 0x43, 0xbe, 0x4d, 0x6d, 0xf9, 0x10, 0x56, 0xe3, 0x0d, + 0x57, 0x52, 0xd7, 0x9f, 0xd8, 0x26, 0xb5, 0x72, 0x19, 0x23, 0xe6, 0xc9, 0xcf, 0x01, 0x12, 0x4b, + 0xa6, 0xce, 0xac, 0xe7, 0x9c, 0xaa, 0x5f, 0xce, 0xc5, 0xd3, 0x5e, 0xc2, 0x5a, 0x7a, 0x4b, 0x76, + 0xb2, 0x4d, 0x29, 0x5a, 0xbd, 0x37, 0x97, 0x8e, 0xc7, 0x1e, 0xc2, 0x6a, 0x1c, 0xd7, 0x29, 0xb3, + 0x82, 0x99, 0x36, 0x9b, 0xcd, 0x85, 0xfc, 0x0a, 0xd6, 0x33, 0x99, 0xd0, 0x66, 0x9a, 0x8a, 0x79, + 0xf5, 0xfe, 0x7c, 0x5e, 0x4c, 0x56, 0x97, 0x3e, 0x4e, 0x86, 0x35, 0x69, 0xef, 0xe0, 0xd7, 0x48, + 0x93, 0xce, 0x47, 0x9a, 0xf4, 0x6f, 0xa4, 0x49, 0x5f, 0xc6, 0x5a, 0xee, 0x7c, 0xac, 0xe5, 0xfe, + 0x8e, 0xb5, 0xdc, 0xeb, 0x07, 0xb6, 0xcb, 0x9c, 0xc1, 0x71, 0xdd, 0xc2, 0x9e, 0xc1, 0x47, 0xfa, + 0x88, 0xbd, 0xc7, 0xe4, 0xd4, 0x48, 0xa7, 0x81, 0x7d, 0xe8, 0x23, 0x7a, 0xbc, 0xcc, 0xff, 0xc9, + 0x9f, 0xfe, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xb3, 0xa2, 0x0a, 0xf6, 0x6b, 0x06, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used.