Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions proto/atomone/gov/v1/gov.proto
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,18 @@ message TallyParams {

// Minimum proportion of Yes votes for proposal to pass. Default value: 2/3.
string threshold = 2 [(cosmos_proto.scalar) = "cosmos.Dec"];

// quorum for constitution amendment proposals
string constitution_amendment_quorum = 3 [(cosmos_proto.scalar) = "cosmos.Dec"];

// Minimum proportion of Yes votes for a Constitution Amendment proposal to pass. Default value: 0.9.
string constitution_amendment_threshold = 4 [(cosmos_proto.scalar) = "cosmos.Dec"];

// quorum for law proposals
string law_quorum = 5 [(cosmos_proto.scalar) = "cosmos.Dec"];

// Minimum proportion of Yes votes for a Law proposal to pass. Default value: 0.9.
string law_threshold = 6 [(cosmos_proto.scalar) = "cosmos.Dec"];
}

// Params defines the parameters for the x/gov module.
Expand Down Expand Up @@ -213,15 +225,24 @@ message Params {
// burn deposits if the proposal does not enter voting period
bool burn_proposal_deposit_prevote = 14;

// burn deposits if quorum with vote type no_veto is met
bool burn_vote_veto = 15;

// The ratio representing the proportion of the deposit value minimum that
// must be met when making a deposit. Default value: 0.01. Meaning that for a
// chain with a min_deposit of 100stake, a deposit of 1stake would be
// required.
//
// Since: cosmos-sdk 0.50
// NOTE: backported from v50 (https://github.com/cosmos/cosmos-sdk/pull/18146)
string min_deposit_ratio = 16 [ (cosmos_proto.scalar) = "cosmos.Dec" ];
string min_deposit_ratio = 15 [ (cosmos_proto.scalar) = "cosmos.Dec" ];

// quorum for constitution amendment proposals
string constitution_amendment_quorum = 16 [(cosmos_proto.scalar) = "cosmos.Dec"];

// Minimum proportion of Yes votes for a Constitution Amendment proposal to pass. Default value: 0.9.
string constitution_amendment_threshold = 17 [(cosmos_proto.scalar) = "cosmos.Dec"];

// quorum for law proposals
string law_quorum = 18 [(cosmos_proto.scalar) = "cosmos.Dec"];

// Minimum proportion of Yes votes for a Law proposal to pass. Default value: 0.9.
string law_threshold = 19 [(cosmos_proto.scalar) = "cosmos.Dec"];
}
26 changes: 26 additions & 0 deletions proto/atomone/gov/v1beta1/gov.proto
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,32 @@ message TextProposal {
string description = 2;
}

message LawProposal {
option (cosmos_proto.implements_interface) = "atomone.gov.v1beta1.Content";
option (amino.name) = "atomone/LawProposal";

option (gogoproto.equal) = true;

// title of the proposal.
string title = 1;

// description associated with the proposal.
string description = 2;
}

message ConstitutionAmendmentProposal {
option (cosmos_proto.implements_interface) = "atomone.gov.v1beta1.Content";
option (amino.name) = "atomone/ConstitutionAmendmentProposal";

option (gogoproto.equal) = true;

// title of the proposal.
string title = 1;

// description associated with the proposal.
string description = 2;
}

// Deposit defines an amount deposited by an account address to an active
// proposal.
message Deposit {
Expand Down
5 changes: 5 additions & 0 deletions tests/e2e/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ func modifyGenesis(path, moniker, amountStr string, addrAll []sdk.AccAddress, de
amnt := sdk.NewInt(10000)
quorum, _ := sdk.NewDecFromStr("0.000000000000000001")
threshold, _ := sdk.NewDecFromStr("0.000000000000000001")
lawQuorum, _ := sdk.NewDecFromStr("0.000000000000000001")
lawThreshold, _ := sdk.NewDecFromStr("0.000000000000000001")
amendmentsQuorum, _ := sdk.NewDecFromStr("0.000000000000000001")
amendmentsThreshold, _ := sdk.NewDecFromStr("0.000000000000000001")

maxDepositPeriod := 10 * time.Minute
votingPeriod := 15 * time.Second
Expand All @@ -133,6 +137,7 @@ func modifyGenesis(path, moniker, amountStr string, addrAll []sdk.AccAddress, de
sdk.NewCoins(sdk.NewCoin(denom, amnt)), maxDepositPeriod,
votingPeriod,
quorum.String(), threshold.String(),
amendmentsQuorum.String(), amendmentsThreshold.String(), lawQuorum.String(), lawThreshold.String(),
sdk.ZeroDec().String(),
false, false, govv1.DefaultMinDepositRatio.String(),
),
Expand Down
34 changes: 31 additions & 3 deletions x/gov/keeper/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ import (
)

var (
_, _, addr = testdata.KeyTestPubAddr()
govAcct = authtypes.NewModuleAddress(types.ModuleName)
TestProposal = getTestProposal()
_, _, addr = testdata.KeyTestPubAddr()
govAcct = authtypes.NewModuleAddress(types.ModuleName)
TestProposal = getTestProposal()
TestAmendmentProposal = getTestConstitutionAmendmentProposal()
TestLawProposal = getTestLawProposal()
)

// getTestProposal creates and returns a test proposal message.
Expand All @@ -46,6 +48,32 @@ func getTestProposal() []sdk.Msg {
}
}

// getTestConstitutionAmendmentProposal creates and returns a test constitution amendment proposal message.
func getTestConstitutionAmendmentProposal() []sdk.Msg {
legacyProposalMsg, err := v1.NewLegacyContent(v1beta1.NewConstitutionAmendmentProposal("Title", "description"), authtypes.NewModuleAddress(types.ModuleName).String())
if err != nil {
panic(err)
}

return []sdk.Msg{
banktypes.NewMsgSend(govAcct, addr, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(1000)))),
legacyProposalMsg,
}
}

// getTestLawProposal creates and returns a test law proposal message.
func getTestLawProposal() []sdk.Msg {
legacyProposalMsg, err := v1.NewLegacyContent(v1beta1.NewLawProposal("Title", "description"), authtypes.NewModuleAddress(types.ModuleName).String())
if err != nil {
panic(err)
}

return []sdk.Msg{
banktypes.NewMsgSend(govAcct, addr, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(1000)))),
legacyProposalMsg,
}
}

type mocks struct {
acctKeeper *govtestutil.MockAccountKeeper
bankKeeper *govtestutil.MockBankKeeper
Expand Down
116 changes: 114 additions & 2 deletions x/gov/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -905,7 +905,7 @@ func (suite *KeeperTestSuite) TestMsgUpdateParams() {
}
},
expErr: true,
expErrMsg: "quorom cannot be negative",
expErrMsg: "quorum must be positive",
},
{
name: "quorum > 1",
Expand All @@ -919,7 +919,7 @@ func (suite *KeeperTestSuite) TestMsgUpdateParams() {
}
},
expErr: true,
expErrMsg: "quorom too large",
expErrMsg: "quorum too large",
},
{
name: "invalid threshold",
Expand Down Expand Up @@ -963,6 +963,118 @@ func (suite *KeeperTestSuite) TestMsgUpdateParams() {
expErr: true,
expErrMsg: "vote threshold too large",
},
{
name: "negative constitution amendment quorum",
input: func() *v1.MsgUpdateParams {
params1 := params
params1.ConstitutionAmendmentQuorum = "-0.1"

return &v1.MsgUpdateParams{
Authority: authority,
Params: params1,
}
},
expErr: true,
expErrMsg: "constitution amendment quorum must be positive",
},
{
name: "constitution amendments quorum > 1",
input: func() *v1.MsgUpdateParams {
params1 := params
params1.ConstitutionAmendmentQuorum = "2"

return &v1.MsgUpdateParams{
Authority: authority,
Params: params1,
}
},
expErr: true,
expErrMsg: "constitution amendment quorum too large",
},
{
name: "negative constitution amendment threshold",
input: func() *v1.MsgUpdateParams {
params1 := params
params1.ConstitutionAmendmentThreshold = "-0.1"

return &v1.MsgUpdateParams{
Authority: authority,
Params: params1,
}
},
expErr: true,
expErrMsg: "constitution amendment threshold must be positive",
},
{
name: "constitution amendments threshold > 1",
input: func() *v1.MsgUpdateParams {
params1 := params
params1.ConstitutionAmendmentThreshold = "2"

return &v1.MsgUpdateParams{
Authority: authority,
Params: params1,
}
},
expErr: true,
expErrMsg: "constitution amendment threshold too large",
},
{
name: "negative law quorum",
input: func() *v1.MsgUpdateParams {
params1 := params
params1.LawQuorum = "-0.1"

return &v1.MsgUpdateParams{
Authority: authority,
Params: params1,
}
},
expErr: true,
expErrMsg: "law quorum must be positive",
},
{
name: "law quorum > 1",
input: func() *v1.MsgUpdateParams {
params1 := params
params1.LawQuorum = "2"

return &v1.MsgUpdateParams{
Authority: authority,
Params: params1,
}
},
expErr: true,
expErrMsg: "law quorum too large",
},
{
name: "negative law threshold",
input: func() *v1.MsgUpdateParams {
params1 := params
params1.LawThreshold = "-0.1"

return &v1.MsgUpdateParams{
Authority: authority,
Params: params1,
}
},
expErr: true,
expErrMsg: "law threshold must be positive",
},
{
name: "law threshold > 1",
input: func() *v1.MsgUpdateParams {
params1 := params
params1.LawThreshold = "2"

return &v1.MsgUpdateParams{
Authority: authority,
Params: params1,
}
},
expErr: true,
expErrMsg: "law threshold too large",
},
{
name: "invalid voting period",
input: func() *v1.MsgUpdateParams {
Expand Down
44 changes: 43 additions & 1 deletion x/gov/keeper/tally.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"

v1 "github.com/atomone-hub/atomone/x/gov/types/v1"
"github.com/atomone-hub/atomone/x/gov/types/v1beta1"
)

// TODO: Break into several smaller functions for clarity
Expand Down Expand Up @@ -85,6 +86,48 @@ func (keeper Keeper) Tally(ctx sdk.Context, proposal v1.Proposal) (passes bool,
// If there is not enough quorum of votes, the proposal fails
percentVoting := totalVotingPower.Quo(sdk.NewDecFromInt(totalBondedTokens))
quorum, _ := sdk.NewDecFromStr(params.Quorum)
threshold, _ := sdk.NewDecFromStr(params.Threshold)

// Check if a proposal message is an ExecLegacyContent message
if len(proposal.Messages) > 0 {
var sdkMsg sdk.Msg
for _, msg := range proposal.Messages {
if err := keeper.cdc.UnpackAny(msg, &sdkMsg); err == nil {
execMsg, ok := sdkMsg.(*v1.MsgExecLegacyContent)
if !ok {
continue
}
var content v1beta1.Content
if err := keeper.cdc.UnpackAny(execMsg.Content, &content); err != nil {
return false, false, tallyResults
}

// Check if proposal is a law or constitution amendment and adjust the
// quorum and threshold accordingly
switch content.(type) {
case *v1beta1.ConstitutionAmendmentProposal:
q, _ := sdk.NewDecFromStr(params.ConstitutionAmendmentQuorum)
if quorum.LT(q) {
quorum = q
}
t, _ := sdk.NewDecFromStr(params.ConstitutionAmendmentThreshold)
if threshold.LT(t) {
threshold = t
}
case *v1beta1.LawProposal:
q, _ := sdk.NewDecFromStr(params.LawQuorum)
if quorum.LT(q) {
quorum = q
}
t, _ := sdk.NewDecFromStr(params.LawThreshold)
if threshold.LT(t) {
threshold = t
}
}
}
}
}

if percentVoting.LT(quorum) {
return false, params.BurnVoteQuorum, tallyResults
}
Expand All @@ -95,7 +138,6 @@ func (keeper Keeper) Tally(ctx sdk.Context, proposal v1.Proposal) (passes bool,
}

// If more than 2/3 of non-abstaining voters vote Yes, proposal passes
threshold, _ := sdk.NewDecFromStr(params.Threshold)
if results[v1.OptionYes].Quo(totalVotingPower.Sub(results[v1.OptionAbstain])).GT(threshold) {
return true, false, tallyResults
}
Expand Down
Loading
Loading