-
Notifications
You must be signed in to change notification settings - Fork 182
/
proposal.go
133 lines (116 loc) · 4.83 KB
/
proposal.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package keeper
import (
"fmt"
"time"
sdk "github.com/okex/exchain/libs/cosmos-sdk/types"
"github.com/okex/exchain/x/common"
"github.com/okex/exchain/x/dex/types"
"github.com/okex/exchain/x/gov"
govTypes "github.com/okex/exchain/x/gov/types"
)
// GetMinDeposit returns min deposit
func (k Keeper) GetMinDeposit(ctx sdk.Context, content gov.Content) (minDeposit sdk.SysCoins) {
if _, ok := content.(types.DelistProposal); ok {
minDeposit = k.GetParams(ctx).DelistMinDeposit
}
return
}
// GetMaxDepositPeriod returns max deposit period
func (k Keeper) GetMaxDepositPeriod(ctx sdk.Context, content gov.Content) (maxDepositPeriod time.Duration) {
if _, ok := content.(types.DelistProposal); ok {
maxDepositPeriod = k.GetParams(ctx).DelistMaxDepositPeriod
}
return
}
// GetVotingPeriod returns voting period
func (k Keeper) GetVotingPeriod(ctx sdk.Context, content gov.Content) (votingPeriod time.Duration) {
if _, ok := content.(types.DelistProposal); ok {
votingPeriod = k.GetParams(ctx).DelistVotingPeriod
}
return
}
// check msg Delist proposal
func (k Keeper) checkMsgDelistProposal(ctx sdk.Context, delistProposal types.DelistProposal, proposer sdk.AccAddress, initialDeposit sdk.SysCoins) sdk.Error {
// check the proposer of the msg is a validator
if !k.stakingKeeper.IsValidator(ctx, proposer) {
return gov.ErrInvalidProposer()
}
// check the propose of the msg is equal the proposer in proposal content
if !proposer.Equals(delistProposal.Proposer) {
return gov.ErrInvalidProposer()
}
// check whether the baseAsset is in the Dex list
queryTokenPair := k.GetTokenPair(ctx, fmt.Sprintf("%s_%s", delistProposal.BaseAsset, delistProposal.QuoteAsset))
if queryTokenPair == nil {
return types.ErrTokenPairNotFound(fmt.Sprintf("%s_%s", delistProposal.BaseAsset, delistProposal.QuoteAsset))
}
// check the initial deposit
localMinDeposit := k.GetParams(ctx).DelistMinDeposit.MulDec(sdk.NewDecWithPrec(1, 1))
err := common.HasSufficientCoins(proposer, initialDeposit, localMinDeposit)
if err != nil {
return types.ErrInvalidAsset(localMinDeposit.String())
}
// check whether the proposer can afford the initial deposit
err = common.HasSufficientCoins(proposer, k.bankKeeper.GetCoins(ctx, proposer), initialDeposit)
if err != nil {
return types.ErrBalanceNotEnough(proposer.String(), initialDeposit.String())
}
return nil
}
// CheckMsgSubmitProposal validates MsgSubmitProposal
func (k Keeper) CheckMsgSubmitProposal(ctx sdk.Context, msg govTypes.MsgSubmitProposal) (sdkErr sdk.Error) {
switch content := msg.Content.(type) {
case types.DelistProposal:
sdkErr = k.checkMsgDelistProposal(ctx, content, msg.Proposer, msg.InitialDeposit)
default:
errContent := fmt.Sprintf("unrecognized dex proposal content type: %T", content)
sdkErr = sdk.ErrUnknownRequest(errContent)
}
return
}
// nolint
func (k Keeper) AfterSubmitProposalHandler(ctx sdk.Context, proposal govTypes.Proposal) {}
// VoteHandler handles delist proposal when voted
func (k Keeper) VoteHandler(ctx sdk.Context, proposal govTypes.Proposal, vote govTypes.Vote) (string, sdk.Error) {
if _, ok := proposal.Content.(types.DelistProposal); ok {
delistProposal := proposal.Content.(types.DelistProposal)
tokenPairName := delistProposal.BaseAsset + "_" + delistProposal.QuoteAsset
if k.IsTokenPairLocked(ctx, tokenPairName) {
errContent := fmt.Sprintf("the trading pair (%s) is locked, please retry later", tokenPairName)
return "", sdk.ErrInternal(errContent)
}
}
return "", nil
}
// RejectedHandler handles delist proposal when rejected
func (k Keeper) RejectedHandler(ctx sdk.Context, content govTypes.Content) {
if content, ok := content.(types.DelistProposal); ok {
tokenPairName := fmt.Sprintf("%s_%s", content.BaseAsset, content.QuoteAsset)
//update the token info from the store
tokenPair := k.GetTokenPair(ctx, tokenPairName)
if tokenPair == nil {
ctx.Logger().Error(fmt.Sprintf("token pair %s does not exist", tokenPairName))
return
}
tokenPair.Delisting = false
k.UpdateTokenPair(ctx, tokenPairName, tokenPair)
}
}
// AfterDepositPeriodPassed handles delist proposal when passed
func (k Keeper) AfterDepositPeriodPassed(ctx sdk.Context, proposal govTypes.Proposal) {
if content, ok := proposal.Content.(types.DelistProposal); ok {
tokenPairName := fmt.Sprintf("%s_%s", content.BaseAsset, content.QuoteAsset)
// change the status of the token pair in the store
tokenPair := k.GetTokenPair(ctx, tokenPairName)
if tokenPair == nil {
ctx.Logger().Error(fmt.Sprintf("token pair %s does not exist", tokenPairName))
return
}
tokenPair.Delisting = true
k.UpdateTokenPair(ctx, tokenPairName, tokenPair)
}
}
// RemoveFromActiveProposalQueue removes active proposal in queue
func (k Keeper) RemoveFromActiveProposalQueue(ctx sdk.Context, proposalID uint64, endTime time.Time) {
k.govKeeper.RemoveFromActiveProposalQueue(ctx, proposalID, endTime)
}