diff --git a/x/farming/keeper/proposal_handler.go b/x/farming/keeper/proposal_handler.go index 65e6ccd0..86bfdb9e 100644 --- a/x/farming/keeper/proposal_handler.go +++ b/x/farming/keeper/proposal_handler.go @@ -37,6 +37,10 @@ func HandlePublicPlanProposal(ctx sdk.Context, k Keeper, proposal *types.PublicP // AddPublicPlanProposal adds a new public plan once the governance proposal is passed. func (k Keeper) AddPublicPlanProposal(ctx sdk.Context, proposals []*types.AddRequestProposal) error { for _, p := range proposals { + if err := p.Validate(); err != nil { + return err + } + farmingPoolAddrAcc, err := sdk.AccAddressFromBech32(p.GetFarmingPoolAddress()) if err != nil { return err @@ -86,6 +90,10 @@ func (k Keeper) AddPublicPlanProposal(ctx sdk.Context, proposals []*types.AddReq // UpdatePublicPlanProposal overwrites the plan with the new plan proposal once the governance proposal is passed. func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.UpdateRequestProposal) error { for _, proposal := range proposals { + if err := proposal.Validate(); err != nil { + return err + } + plan, found := k.GetPlan(ctx, proposal.GetPlanId()) if !found { return sdkerrors.Wrapf(sdkerrors.ErrNotFound, "plan %d is not found", proposal.GetPlanId()) @@ -161,6 +169,10 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd // DeletePublicPlanProposal delets public plan proposal once the governance proposal is passed. func (k Keeper) DeletePublicPlanProposal(ctx sdk.Context, proposals []*types.DeleteRequestProposal) error { for _, p := range proposals { + if err := p.Validate(); err != nil { + return err + } + plan, found := k.GetPlan(ctx, p.GetPlanId()) if !found { return sdkerrors.Wrapf(sdkerrors.ErrNotFound, "plan %d is not found", p.GetPlanId()) diff --git a/x/farming/types/plan.go b/x/farming/types/plan.go index 19938e54..90c57f0a 100644 --- a/x/farming/types/plan.go +++ b/x/farming/types/plan.go @@ -130,7 +130,7 @@ func (plan BasePlan) Validate() error { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid termination address %q: %v", plan.TerminationAddress, err) } if len(plan.Name) > MaxNameLength { - return sdkerrors.Wrapf(ErrInvalidNameLength, "plan name is longer than max length of %d", MaxNameLength) + return sdkerrors.Wrapf(ErrInvalidNameLength, "plan name cannot be longer than max length of %d", MaxNameLength) } if err := plan.StakingCoinWeights.Validate(); err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid staking coin weights: %v", err) diff --git a/x/farming/types/proposal.go b/x/farming/types/proposal.go index 9c4d37e9..142818b2 100644 --- a/x/farming/types/proposal.go +++ b/x/farming/types/proposal.go @@ -3,6 +3,7 @@ package types import ( "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" gov "github.com/cosmos/cosmos-sdk/x/gov/types" ) @@ -54,3 +55,57 @@ func (p PublicPlanProposal) String() string { DeleteRequestProposals: %s `, p.Title, p.Description, p.AddRequestProposals, p.UpdateRequestProposals, p.DeleteRequestProposals) } + +func (p *AddRequestProposal) Validate() error { + if len(p.Name) > MaxNameLength { + return sdkerrors.Wrapf(ErrInvalidNameLength, "plan name cannot be longer than max length of %d", MaxNameLength) + } + if _, err := sdk.AccAddressFromBech32(p.FarmingPoolAddress); err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid farming pool address %q: %v", p.FarmingPoolAddress, err) + } + if _, err := sdk.AccAddressFromBech32(p.TerminationAddress); err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid termination address %q: %v", p.TerminationAddress, err) + } + if err := p.StakingCoinWeights.Validate(); err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid staking coin weights: %v", err) + } + if !p.EndTime.After(p.StartTime) { + return sdkerrors.Wrapf(ErrInvalidPlanEndTime, "end time %s must be greater than start time %s", p.EndTime, p.StartTime) + } + if !p.EpochAmount.Empty() && !p.EpochRatio.IsZero() { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "epoch amount or epoch ratio must be provided") + } + return nil +} + +func (p *UpdateRequestProposal) Validate() error { + if p.PlanId == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid plan id: %d", p.PlanId) + } + if len(p.Name) > MaxNameLength { + return sdkerrors.Wrapf(ErrInvalidNameLength, "plan name cannot be longer than max length of %d", MaxNameLength) + } + if _, err := sdk.AccAddressFromBech32(p.FarmingPoolAddress); err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid farming pool address %q: %v", p.FarmingPoolAddress, err) + } + if _, err := sdk.AccAddressFromBech32(p.TerminationAddress); err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid termination address %q: %v", p.TerminationAddress, err) + } + if err := p.StakingCoinWeights.Validate(); err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid staking coin weights: %v", err) + } + if !p.EndTime.After(p.StartTime) { + return sdkerrors.Wrapf(ErrInvalidPlanEndTime, "end time %s must be greater than start time %s", p.EndTime, p.StartTime) + } + if !p.EpochAmount.Empty() && !p.EpochRatio.IsZero() { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "epoch amount or epoch ratio must be provided") + } + return nil +} + +func (p *DeleteRequestProposal) Validate() error { + if p.PlanId == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid plan id: %d", p.PlanId) + } + return nil +}