github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/gov/keeper/deposit.go (about)

     1  package keeper
     2  
     3  import (
     4  	"fmt"
     5  
     6  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     7  	sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors"
     8  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/gov/types"
     9  )
    10  
    11  // GetDeposit gets the deposit of a specific depositor on a specific proposal
    12  func (keeper Keeper) GetDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress) (deposit types.Deposit, found bool) {
    13  	store := ctx.KVStore(keeper.storeKey)
    14  	bz := store.Get(types.DepositKey(proposalID, depositorAddr))
    15  	if bz == nil {
    16  		return deposit, false
    17  	}
    18  
    19  	keeper.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &deposit)
    20  	return deposit, true
    21  }
    22  
    23  // SetDeposit sets a Deposit to the gov store
    24  func (keeper Keeper) SetDeposit(ctx sdk.Context, deposit types.Deposit) {
    25  	store := ctx.KVStore(keeper.storeKey)
    26  	bz := keeper.cdc.MustMarshalBinaryLengthPrefixed(deposit)
    27  	store.Set(types.DepositKey(deposit.ProposalID, deposit.Depositor), bz)
    28  }
    29  
    30  // GetAllDeposits returns all the deposits from the store
    31  func (keeper Keeper) GetAllDeposits(ctx sdk.Context) (deposits types.Deposits) {
    32  	keeper.IterateAllDeposits(ctx, func(deposit types.Deposit) bool {
    33  		deposits = append(deposits, deposit)
    34  		return false
    35  	})
    36  	return
    37  }
    38  
    39  // GetDeposits returns all the deposits from a proposal
    40  func (keeper Keeper) GetDeposits(ctx sdk.Context, proposalID uint64) (deposits types.Deposits) {
    41  	keeper.IterateDeposits(ctx, proposalID, func(deposit types.Deposit) bool {
    42  		deposits = append(deposits, deposit)
    43  		return false
    44  	})
    45  	return
    46  }
    47  
    48  // DeleteDeposits deletes all the deposits on a specific proposal without refunding them
    49  func (keeper Keeper) DeleteDeposits(ctx sdk.Context, proposalID uint64) {
    50  	store := ctx.KVStore(keeper.storeKey)
    51  
    52  	keeper.IterateDeposits(ctx, proposalID, func(deposit types.Deposit) bool {
    53  		err := keeper.supplyKeeper.BurnCoins(ctx, types.ModuleName, deposit.Amount)
    54  		if err != nil {
    55  			panic(err)
    56  		}
    57  
    58  		store.Delete(types.DepositKey(proposalID, deposit.Depositor))
    59  		return false
    60  	})
    61  }
    62  
    63  // IterateAllDeposits iterates over the all the stored deposits and performs a callback function
    64  func (keeper Keeper) IterateAllDeposits(ctx sdk.Context, cb func(deposit types.Deposit) (stop bool)) {
    65  	store := ctx.KVStore(keeper.storeKey)
    66  	iterator := sdk.KVStorePrefixIterator(store, types.DepositsKeyPrefix)
    67  
    68  	defer iterator.Close()
    69  	for ; iterator.Valid(); iterator.Next() {
    70  		var deposit types.Deposit
    71  		keeper.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &deposit)
    72  
    73  		if cb(deposit) {
    74  			break
    75  		}
    76  	}
    77  }
    78  
    79  // IterateDeposits iterates over the all the proposals deposits and performs a callback function
    80  func (keeper Keeper) IterateDeposits(ctx sdk.Context, proposalID uint64, cb func(deposit types.Deposit) (stop bool)) {
    81  	store := ctx.KVStore(keeper.storeKey)
    82  	iterator := sdk.KVStorePrefixIterator(store, types.DepositsKey(proposalID))
    83  
    84  	defer iterator.Close()
    85  	for ; iterator.Valid(); iterator.Next() {
    86  		var deposit types.Deposit
    87  		keeper.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &deposit)
    88  
    89  		if cb(deposit) {
    90  			break
    91  		}
    92  	}
    93  }
    94  
    95  // AddDeposit adds or updates a deposit of a specific depositor on a specific proposal
    96  // Activates voting period when appropriate
    97  func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress, depositAmount sdk.Coins) (bool, error) {
    98  	// Checks to see if proposal exists
    99  	proposal, ok := keeper.GetProposal(ctx, proposalID)
   100  	if !ok {
   101  		return false, sdkerrors.Wrapf(types.ErrUnknownProposal, "%d", proposalID)
   102  	}
   103  
   104  	// Check if proposal is still depositable
   105  	if (proposal.Status != types.StatusDepositPeriod) && (proposal.Status != types.StatusVotingPeriod) {
   106  		return false, sdkerrors.Wrapf(types.ErrInactiveProposal, "%d", proposalID)
   107  	}
   108  
   109  	// update the governance module's account coins pool
   110  	err := keeper.supplyKeeper.SendCoinsFromAccountToModule(ctx, depositorAddr, types.ModuleName, depositAmount)
   111  	if err != nil {
   112  		return false, err
   113  	}
   114  
   115  	// Update proposal
   116  	proposal.TotalDeposit = proposal.TotalDeposit.Add(depositAmount...)
   117  	keeper.SetProposal(ctx, proposal)
   118  
   119  	// Check if deposit has provided sufficient total funds to transition the proposal into the voting period
   120  	activatedVotingPeriod := false
   121  	if proposal.Status == types.StatusDepositPeriod && proposal.TotalDeposit.IsAllGTE(keeper.GetDepositParams(ctx).MinDeposit) {
   122  		keeper.activateVotingPeriod(ctx, proposal)
   123  		activatedVotingPeriod = true
   124  	}
   125  
   126  	// Add or update deposit object
   127  	deposit, found := keeper.GetDeposit(ctx, proposalID, depositorAddr)
   128  	if found {
   129  		deposit.Amount = deposit.Amount.Add(depositAmount...)
   130  	} else {
   131  		deposit = types.NewDeposit(proposalID, depositorAddr, depositAmount)
   132  	}
   133  
   134  	ctx.EventManager().EmitEvent(
   135  		sdk.NewEvent(
   136  			types.EventTypeProposalDeposit,
   137  			sdk.NewAttribute(sdk.AttributeKeyAmount, depositAmount.String()),
   138  			sdk.NewAttribute(types.AttributeKeyProposalID, fmt.Sprintf("%d", proposalID)),
   139  		),
   140  	)
   141  
   142  	keeper.SetDeposit(ctx, deposit)
   143  	return activatedVotingPeriod, nil
   144  }
   145  
   146  // RefundDeposits refunds and deletes all the deposits on a specific proposal
   147  func (keeper Keeper) RefundDeposits(ctx sdk.Context, proposalID uint64) {
   148  	store := ctx.KVStore(keeper.storeKey)
   149  
   150  	keeper.IterateDeposits(ctx, proposalID, func(deposit types.Deposit) bool {
   151  		err := keeper.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, deposit.Depositor, deposit.Amount)
   152  		if err != nil {
   153  			panic(err)
   154  		}
   155  
   156  		store.Delete(types.DepositKey(proposalID, deposit.Depositor))
   157  		return false
   158  	})
   159  }