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

     1  package farm
     2  
     3  import (
     4  	"fmt"
     5  
     6  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     7  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
     8  	"github.com/fibonacci-chain/fbc/x/farm/keeper"
     9  	"github.com/fibonacci-chain/fbc/x/farm/types"
    10  )
    11  
    12  // BeginBlocker allocates the native token to the pools in PoolsYieldNativeToken
    13  // according to the value of locked token in pool
    14  func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k keeper.Keeper) {
    15  	logger := k.Logger(ctx)
    16  
    17  	moduleAcc := k.SupplyKeeper().GetModuleAccount(ctx, MintFarmingAccount)
    18  	yieldedNativeTokenAmt := moduleAcc.GetCoins().AmountOf(sdk.DefaultBondDenom)
    19  	logger.Debug(fmt.Sprintf("MintFarmingAccount [%s] balance: %s%s",
    20  		moduleAcc.GetAddress(), yieldedNativeTokenAmt, sdk.DefaultBondDenom))
    21  
    22  	if yieldedNativeTokenAmt.LTE(sdk.ZeroDec()) {
    23  		return
    24  	}
    25  
    26  	yieldedNativeToken := sdk.NewDecCoinsFromDec(sdk.DefaultBondDenom, yieldedNativeTokenAmt)
    27  	// 0. check the YieldNativeToken parameters
    28  	params := k.GetParams(ctx)
    29  	if !params.YieldNativeToken { // if it is false, only burn the minted native token
    30  		if err := k.SupplyKeeper().BurnCoins(ctx, MintFarmingAccount, yieldedNativeToken); err != nil {
    31  			panic(err)
    32  		}
    33  		return
    34  	}
    35  
    36  	// 1. gets all pools in PoolsYieldNativeToken
    37  	lockedPoolValueMap, pools, totalPoolsValue := calculateAllocateInfo(ctx, k)
    38  	if totalPoolsValue.LTE(sdk.ZeroDec()) {
    39  		return
    40  	}
    41  
    42  	// 2. allocate native token to pools according to the value
    43  	remainingNativeTokenAmt := yieldedNativeTokenAmt
    44  	for i, pool := range pools {
    45  		var allocatedAmt sdk.Dec
    46  		if i == len(pools)-1 {
    47  			allocatedAmt = remainingNativeTokenAmt
    48  		} else {
    49  			allocatedAmt = lockedPoolValueMap[pool.Name].
    50  				MulTruncate(yieldedNativeTokenAmt).QuoTruncate(totalPoolsValue)
    51  		}
    52  		remainingNativeTokenAmt = remainingNativeTokenAmt.Sub(allocatedAmt)
    53  		logger.Debug(
    54  			fmt.Sprintf("Pool %s allocate %s yielded native token", pool.Name, allocatedAmt.String()),
    55  		)
    56  		allocatedCoins := sdk.NewDecCoinsFromDec(sdk.DefaultBondDenom, allocatedAmt)
    57  
    58  		current := k.GetPoolCurrentRewards(ctx, pool.Name)
    59  		current.Rewards = current.Rewards.Add2(allocatedCoins)
    60  		k.SetPoolCurrentRewards(ctx, pool.Name, current)
    61  		logger.Debug(fmt.Sprintf("Pool %s rewards are %s", pool.Name, current.Rewards))
    62  
    63  		pool.TotalAccumulatedRewards = pool.TotalAccumulatedRewards.Add2(allocatedCoins)
    64  		k.SetFarmPool(ctx, pool)
    65  	}
    66  	if !remainingNativeTokenAmt.IsZero() {
    67  		panic(fmt.Sprintf("there are some tokens %s not to be allocated", remainingNativeTokenAmt))
    68  	}
    69  
    70  	// 3.liquidate native token minted at current block for yield farming
    71  	err := k.SupplyKeeper().SendCoinsFromModuleToModule(ctx, MintFarmingAccount, YieldFarmingAccount, yieldedNativeToken)
    72  	if err != nil {
    73  		panic("should not happen")
    74  	}
    75  }
    76  
    77  // EndBlocker called every block, process inflation, update validator set.
    78  func EndBlocker(ctx sdk.Context, k keeper.Keeper) {
    79  
    80  }
    81  
    82  // calculateAllocateInfo gets all pools in PoolsYieldNativeToken
    83  func calculateAllocateInfo(ctx sdk.Context, k keeper.Keeper) (map[string]sdk.Dec, []types.FarmPool, sdk.Dec) {
    84  	lockedPoolValue := make(map[string]sdk.Dec)
    85  	var pools types.FarmPools
    86  	totalPoolsValue := sdk.ZeroDec()
    87  
    88  	store := ctx.KVStore(k.StoreKey())
    89  	iterator := sdk.KVStorePrefixIterator(store, types.PoolsYieldNativeTokenPrefix)
    90  	defer iterator.Close()
    91  	for ; iterator.Valid(); iterator.Next() {
    92  		poolName := types.SplitPoolsYieldNativeTokenKey(iterator.Key())
    93  		pool, found := k.GetFarmPool(ctx, poolName)
    94  		if !found {
    95  			panic("should not happen")
    96  		}
    97  		poolValue := k.GetPoolLockedValue(ctx, pool)
    98  		if poolValue.LTE(sdk.ZeroDec()) {
    99  			continue
   100  		}
   101  		pools = append(pools, pool)
   102  		lockedPoolValue[poolName] = poolValue
   103  		totalPoolsValue = totalPoolsValue.Add(poolValue)
   104  	}
   105  	return lockedPoolValue, pools, totalPoolsValue
   106  }