github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/gov/keeper/deposit.go (about) 1 package keeper 2 3 import ( 4 "fmt" 5 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 6 "github.com/fibonacci-chain/fbc/x/gov/types" 7 ) 8 9 // SetDeposit sets the deposit of a specific depositor on a specific proposal 10 func (keeper Keeper) SetDeposit(ctx sdk.Context, deposit types.Deposit) { 11 store := ctx.KVStore(keeper.storeKey) 12 bz := keeper.cdc.MustMarshalBinaryLengthPrefixed(deposit) 13 store.Set(types.DepositKey(deposit.ProposalID, deposit.Depositor), bz) 14 } 15 16 func tryEnterVotingPeriod( 17 ctx sdk.Context, keeper Keeper, proposal *types.Proposal, depositAmount sdk.SysCoins, eventType string, 18 ) { 19 // Update proposal 20 proposal.TotalDeposit = proposal.TotalDeposit.Add(depositAmount...) 21 // Check if deposit has provided sufficient total funds to transition the proposal into the voting period 22 activatedVotingPeriod := false 23 var minDeposit sdk.SysCoins 24 if !keeper.proposalHandlerRouter.HasRoute(proposal.ProposalRoute()) { 25 minDeposit = keeper.GetDepositParams(ctx).MinDeposit 26 } else { 27 phr := keeper.proposalHandlerRouter.GetRoute(proposal.ProposalRoute()) 28 minDeposit = phr.GetMinDeposit(ctx, proposal.Content) 29 } 30 31 if proposal.Status == types.StatusDepositPeriod && proposal.TotalDeposit.IsAllGTE(minDeposit) { 32 keeper.activateVotingPeriod(ctx, proposal) 33 activatedVotingPeriod = true 34 proposal.DepositEndTime = ctx.BlockHeader().Time 35 } 36 keeper.SetProposal(ctx, *proposal) 37 38 if activatedVotingPeriod { 39 // execute the logic when the deposit period is passed 40 if !keeper.ProposalHandlerRouter().HasRoute(proposal.Content.ProposalRoute()) { 41 keeper.AfterDepositPeriodPassed(ctx, *proposal) 42 } else { 43 proposalHandler := keeper.ProposalHandlerRouter().GetRoute(proposal.Content.ProposalRoute()) 44 proposalHandler.AfterDepositPeriodPassed(ctx, *proposal) 45 } 46 47 ctx.EventManager().EmitEvent( 48 sdk.NewEvent( 49 eventType, 50 sdk.NewAttribute(types.AttributeKeyVotingPeriodStart, fmt.Sprintf("%d", proposal.ProposalID)), 51 ), 52 ) 53 } 54 } 55 56 func updateDeposit( 57 ctx sdk.Context, keeper Keeper, proposalID uint64, depositorAddr sdk.AccAddress, depositAmount sdk.SysCoins, 58 ) { 59 deposit, found := keeper.GetDeposit(ctx, proposalID, depositorAddr) 60 if found { 61 deposit.Amount = deposit.Amount.Add(depositAmount...) 62 } else { 63 deposit = types.Deposit{ 64 ProposalID: proposalID, 65 Depositor: depositorAddr, 66 Amount: depositAmount, 67 } 68 } 69 keeper.SetDeposit(ctx, deposit) 70 } 71 72 // AddDeposit adds or updates a deposit of a specific depositor on a specific proposal 73 // Activates voting period when appropriate 74 func (keeper Keeper) AddDeposit( 75 ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress, 76 depositAmount sdk.SysCoins, eventType string, 77 ) sdk.Error { 78 // Checks to see if proposal exists 79 proposal, ok := keeper.GetProposal(ctx, proposalID) 80 if !ok { 81 return types.ErrUnknownProposal(proposalID) 82 } 83 84 // Check if proposal is still depositable 85 if proposal.Status != types.StatusDepositPeriod { 86 return types.ErrInvalidateProposalStatus() 87 } 88 depositCoinsAmount := depositAmount 89 // update the governance module's account coins pool 90 err := keeper.supplyKeeper.SendCoinsFromAccountToModule(ctx, depositorAddr, types.ModuleName, depositCoinsAmount) 91 if err != nil { 92 return err 93 } 94 95 // try enter voting period according to proposal's total deposit 96 tryEnterVotingPeriod(ctx, keeper, &proposal, depositAmount, eventType) 97 98 // Add or update deposit object 99 updateDeposit(ctx, keeper, proposalID, depositorAddr, depositAmount) 100 101 ctx.EventManager().EmitEvent( 102 sdk.NewEvent( 103 types.EventTypeProposalDeposit, 104 sdk.NewAttribute(sdk.AttributeKeyAmount, depositAmount.String()), 105 sdk.NewAttribute(types.AttributeKeyProposalID, fmt.Sprintf("%d", proposalID)), 106 ), 107 ) 108 109 return nil 110 } 111 112 // RefundDeposits refunds and deletes all the deposits on a specific proposal 113 func (keeper Keeper) RefundDeposits(ctx sdk.Context, proposalID uint64) { 114 deposits := keeper.GetDeposits(ctx, proposalID) 115 for i := 0; i < len(deposits); i++ { 116 deposit := deposits[i] 117 err := keeper.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, deposit.Depositor, 118 deposit.Amount) 119 if err != nil { 120 panic(err) 121 } 122 keeper.deleteDeposit(ctx, proposalID, deposit.Depositor) 123 } 124 } 125 126 // DistributeDeposits distributes and deletes all the deposits on a specific proposal 127 func (keeper Keeper) DistributeDeposits(ctx sdk.Context, proposalID uint64) { 128 deposits := keeper.GetDeposits(ctx, proposalID) 129 for i := 0; i < len(deposits); i++ { 130 deposit := deposits[i] 131 err := keeper.supplyKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, keeper.feeCollectorName, 132 deposit.Amount) 133 if err != nil { 134 panic(err) 135 } 136 keeper.deleteDeposit(ctx, proposalID, deposit.Depositor) 137 } 138 } 139 140 func (keeper Keeper) deleteDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress) { 141 store := ctx.KVStore(keeper.storeKey) 142 store.Delete(types.DepositKey(proposalID, depositorAddr)) 143 } 144 145 // GetDeposit gets the deposit of a specific depositor on a specific proposal 146 func (keeper Keeper) GetDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress) (deposit types.Deposit, found bool) { 147 store := ctx.KVStore(keeper.storeKey) 148 bz := store.Get(types.DepositKey(proposalID, depositorAddr)) 149 if bz == nil { 150 return deposit, false 151 } 152 153 keeper.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &deposit) 154 return deposit, true 155 } 156 157 func (keeper Keeper) setDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress, deposit types.Deposit) { 158 store := ctx.KVStore(keeper.storeKey) 159 bz := keeper.cdc.MustMarshalBinaryLengthPrefixed(deposit) 160 store.Set(types.DepositKey(proposalID, depositorAddr), bz) 161 } 162 163 // GetAllDeposits returns all the deposits from the store 164 func (keeper Keeper) GetAllDeposits(ctx sdk.Context) (deposits types.Deposits) { 165 keeper.IterateAllDeposits(ctx, func(deposit types.Deposit) bool { 166 deposits = append(deposits, deposit) 167 return false 168 }) 169 return 170 } 171 172 // GetDeposits returns all the deposits from a proposal 173 func (keeper Keeper) GetDeposits(ctx sdk.Context, proposalID uint64) (deposits types.Deposits) { 174 keeper.IterateDeposits(ctx, proposalID, func(deposit types.Deposit) bool { 175 deposits = append(deposits, deposit) 176 return false 177 }) 178 return 179 } 180 181 // GetDepositsIterator gets all the deposits on a specific proposal as an sdk.Iterator 182 func (keeper Keeper) GetDepositsIterator(ctx sdk.Context, proposalID uint64) sdk.Iterator { 183 store := ctx.KVStore(keeper.storeKey) 184 return sdk.KVStorePrefixIterator(store, types.DepositsKey(proposalID)) 185 } 186 187 // DeleteDeposits deletes all the deposits on a specific proposal without refunding them 188 func (keeper Keeper) DeleteDeposits(ctx sdk.Context, proposalID uint64) { 189 store := ctx.KVStore(keeper.storeKey) 190 191 keeper.IterateDeposits(ctx, proposalID, func(deposit types.Deposit) bool { 192 err := keeper.supplyKeeper.BurnCoins(ctx, types.ModuleName, deposit.Amount) 193 if err != nil { 194 panic(err) 195 } 196 197 store.Delete(types.DepositKey(proposalID, deposit.Depositor)) 198 return false 199 }) 200 }