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