github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/distribution/keeper/keeper.go (about)

     1  package keeper
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
     7  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     8  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/log"
     9  	"github.com/fibonacci-chain/fbc/x/params"
    10  
    11  	"github.com/fibonacci-chain/fbc/x/distribution/types"
    12  )
    13  
    14  // Keeper of the distribution store
    15  type Keeper struct {
    16  	storeKey      sdk.StoreKey
    17  	cdc           *codec.Codec
    18  	paramSpace    params.Subspace
    19  	stakingKeeper types.StakingKeeper
    20  	supplyKeeper  types.SupplyKeeper
    21  	govKeeper     types.GovKeeper
    22  
    23  	blacklistedAddrs map[string]bool
    24  
    25  	feeCollectorName string // name of the FeeCollector ModuleAccount
    26  }
    27  
    28  // NewKeeper creates a new distribution Keeper instance
    29  func NewKeeper(
    30  	cdc *codec.Codec, key sdk.StoreKey, paramSpace params.Subspace,
    31  	sk types.StakingKeeper, supplyKeeper types.SupplyKeeper, feeCollectorName string,
    32  	blacklistedAddrs map[string]bool,
    33  ) Keeper {
    34  
    35  	// ensure distribution module account is set
    36  	if addr := supplyKeeper.GetModuleAddress(types.ModuleName); addr == nil {
    37  		panic(fmt.Sprintf("%s module account has not been set", types.ModuleName))
    38  	}
    39  
    40  	// set KeyTable if it has not already been set
    41  	if !paramSpace.HasKeyTable() {
    42  		paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable())
    43  	}
    44  
    45  	return Keeper{
    46  		storeKey:         key,
    47  		cdc:              cdc,
    48  		paramSpace:       paramSpace,
    49  		stakingKeeper:    sk,
    50  		supplyKeeper:     supplyKeeper,
    51  		feeCollectorName: feeCollectorName,
    52  		blacklistedAddrs: blacklistedAddrs,
    53  	}
    54  }
    55  
    56  // Logger returns a module-specific logger.
    57  func (k Keeper) Logger(ctx sdk.Context) log.Logger {
    58  	return ctx.Logger().With("module", types.ShortUseByCli)
    59  }
    60  
    61  // SetWithdrawAddr sets a new address that will receive the rewards upon withdrawal
    62  func (k Keeper) SetWithdrawAddr(ctx sdk.Context, delegatorAddr sdk.AccAddress, withdrawAddr sdk.AccAddress) error {
    63  	if k.blacklistedAddrs[withdrawAddr.String()] {
    64  		return types.ErrWithdrawAddrInblacklist()
    65  	}
    66  
    67  	if !k.GetWithdrawAddrEnabled(ctx) {
    68  		return types.ErrSetWithdrawAddrDisabled()
    69  	}
    70  
    71  	ctx.EventManager().EmitEvent(
    72  		sdk.NewEvent(
    73  			types.EventTypeSetWithdrawAddress,
    74  			sdk.NewAttribute(types.AttributeKeyWithdrawAddress, withdrawAddr.String()),
    75  		),
    76  	)
    77  
    78  	k.SetDelegatorWithdrawAddr(ctx, delegatorAddr, withdrawAddr)
    79  	return nil
    80  }
    81  
    82  // WithdrawValidatorCommission withdraws validator commission
    83  func (k Keeper) WithdrawValidatorCommission(ctx sdk.Context, valAddr sdk.ValAddress) (sdk.Coins, error) {
    84  	// fetch validator accumulated commission
    85  	accumCommission := k.GetValidatorAccumulatedCommission(ctx, valAddr)
    86  	if accumCommission.IsZero() {
    87  		return nil, types.ErrNoValidatorCommission()
    88  	}
    89  
    90  	commission, remainder := accumCommission.TruncateDecimal()
    91  	k.SetValidatorAccumulatedCommission(ctx, valAddr, remainder) // leave remainder to withdraw later
    92  
    93  	if k.CheckDistributionProposalValid(ctx) {
    94  		// update outstanding
    95  		outstanding := k.GetValidatorOutstandingRewards(ctx, valAddr)
    96  		k.SetValidatorOutstandingRewards(ctx, valAddr, outstanding.Sub(sdk.NewDecCoinsFromCoins(commission...)))
    97  	}
    98  
    99  	if !commission.IsZero() {
   100  		accAddr := sdk.AccAddress(valAddr)
   101  		withdrawAddr := k.GetDelegatorWithdrawAddr(ctx, accAddr)
   102  		err := k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, withdrawAddr, commission)
   103  		if err != nil {
   104  			return nil, types.ErrSendCoinsFromModuleToAccountFailed()
   105  		}
   106  	}
   107  
   108  	ctx.EventManager().EmitEvent(
   109  		sdk.NewEvent(
   110  			types.EventTypeWithdrawCommission,
   111  			sdk.NewAttribute(sdk.AttributeKeyAmount, commission.String()),
   112  		),
   113  	)
   114  
   115  	return commission, nil
   116  }