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

     1  package farm
     2  
     3  import (
     4  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     5  	"github.com/fibonacci-chain/fbc/x/common"
     6  	"github.com/fibonacci-chain/fbc/x/farm/keeper"
     7  	"github.com/fibonacci-chain/fbc/x/farm/types"
     8  )
     9  
    10  func handleMsgCreatePool(ctx sdk.Context, k keeper.Keeper, msg types.MsgCreatePool) (*sdk.Result, error) {
    11  	if _, found := k.GetFarmPool(ctx, msg.PoolName); found {
    12  		return types.ErrPoolAlreadyExist(msg.PoolName).Result()
    13  	}
    14  
    15  	if ok := k.TokenKeeper().TokenExist(ctx, msg.MinLockAmount.Denom); !ok {
    16  		return types.ErrTokenNotExist(msg.MinLockAmount.Denom).Result()
    17  	}
    18  
    19  	if ok := k.TokenKeeper().TokenExist(ctx, msg.YieldedSymbol); !ok {
    20  		return types.ErrTokenNotExist(msg.YieldedSymbol).Result()
    21  	}
    22  
    23  	// fee
    24  	params := k.GetParams(ctx)
    25  	feeAmount := params.CreatePoolFee
    26  	if err := k.SupplyKeeper().SendCoinsFromAccountToModule(
    27  		ctx, msg.Owner, k.GetFeeCollector(), feeAmount.ToCoins(),
    28  	); err != nil {
    29  		return nil, common.ErrInsufficientCoins(DefaultParamspace, err.Error())
    30  	}
    31  
    32  	// deposit
    33  	depositAmount := params.CreatePoolDeposit
    34  	if err := k.SupplyKeeper().SendCoinsFromAccountToModule(
    35  		ctx, msg.Owner, ModuleName, depositAmount.ToCoins(),
    36  	); err != nil {
    37  		return nil, common.ErrInsufficientCoins(DefaultParamspace, err.Error())
    38  	}
    39  
    40  	// create pool
    41  	yieldedTokenInfo := types.NewYieldedTokenInfo(sdk.NewDecCoin(msg.YieldedSymbol, sdk.ZeroInt()),
    42  		0, sdk.ZeroDec())
    43  	pool := types.NewFarmPool(
    44  		msg.Owner, msg.PoolName, msg.MinLockAmount, depositAmount, sdk.NewDecCoin(msg.MinLockAmount.Denom, sdk.ZeroInt()),
    45  		[]types.YieldedTokenInfo{yieldedTokenInfo}, sdk.SysCoins{},
    46  	)
    47  	k.SetFarmPool(ctx, pool)
    48  
    49  	// initial pool period
    50  	poolHistoricalRewards := types.NewPoolHistoricalRewards(sdk.SysCoins{}, 1)
    51  	k.SetPoolHistoricalRewards(ctx, msg.PoolName, 0, poolHistoricalRewards)
    52  	poolCurrentRewards := types.NewPoolCurrentRewards(ctx.BlockHeight(), 1, sdk.SysCoins{})
    53  	k.SetPoolCurrentRewards(ctx, msg.PoolName, poolCurrentRewards)
    54  
    55  	ctx.EventManager().EmitEvent(sdk.NewEvent(
    56  		types.EventTypeCreatePool,
    57  		sdk.NewAttribute(types.AttributeKeyAddress, msg.Owner.String()),
    58  		sdk.NewAttribute(types.AttributeKeyPool, msg.PoolName),
    59  		sdk.NewAttribute(types.AttributeKeyMinLockAmount, msg.MinLockAmount.String()),
    60  		sdk.NewAttribute(types.AttributeKeyYieldToken, msg.YieldedSymbol),
    61  		sdk.NewAttribute(sdk.AttributeKeyFee, feeAmount.String()),
    62  		sdk.NewAttribute(types.AttributeKeyDeposit, depositAmount.String()),
    63  	))
    64  	return &sdk.Result{Events: ctx.EventManager().Events()}, nil
    65  }
    66  
    67  func handleMsgDestroyPool(ctx sdk.Context, k keeper.Keeper, msg types.MsgDestroyPool) (*sdk.Result, error) {
    68  	// 0. check pool and owner
    69  	pool, found := k.GetFarmPool(ctx, msg.PoolName)
    70  	if !found {
    71  		return types.ErrNoFarmPoolFound(msg.PoolName).Result()
    72  	}
    73  
    74  	if !pool.Owner.Equals(msg.Owner) {
    75  		return types.ErrInvalidPoolOwner(msg.Owner.String(), msg.PoolName).Result()
    76  	}
    77  
    78  	// 1. calculate how many provided token & native token could be yielded in current period
    79  	updatedPool, _ := k.CalculateAmountYieldedBetween(ctx, pool)
    80  
    81  	// 2. check pool status
    82  	if !updatedPool.Finished() {
    83  		return types.ErrPoolNotFinished(msg.PoolName).Result()
    84  	}
    85  
    86  	// 3. give remaining rewards to the owner of pool
    87  	if !updatedPool.TotalAccumulatedRewards.IsZero() {
    88  		err := k.SupplyKeeper().SendCoinsFromModuleToAccount(
    89  			ctx, YieldFarmingAccount, msg.Owner, updatedPool.TotalAccumulatedRewards,
    90  		)
    91  		if err != nil {
    92  			return nil, common.ErrInsufficientCoins(DefaultParamspace, err.Error())
    93  		}
    94  	}
    95  
    96  	// 4. withdraw deposit
    97  	withdrawAmount := pool.DepositAmount
    98  	if withdrawAmount.IsPositive() {
    99  		err := k.SupplyKeeper().SendCoinsFromModuleToAccount(ctx, ModuleName, msg.Owner, withdrawAmount.ToCoins())
   100  		if err != nil {
   101  			return nil, common.ErrInsufficientCoins(DefaultParamspace, err.Error())
   102  		}
   103  	}
   104  
   105  	// 5. delete pool and white list
   106  	k.DeleteFarmPool(ctx, msg.PoolName)
   107  
   108  	// 6. delete historical period rewards and current period rewards.
   109  	k.IteratePoolHistoricalRewards(ctx, msg.PoolName,
   110  		func(store sdk.KVStore, key []byte, value []byte) (stop bool) {
   111  			store.Delete(key)
   112  			return false
   113  		},
   114  	)
   115  	k.DeletePoolCurrentRewards(ctx, msg.PoolName)
   116  
   117  	ctx.EventManager().EmitEvent(sdk.NewEvent(
   118  		types.EventTypeDestroyPool,
   119  		sdk.NewAttribute(types.AttributeKeyAddress, msg.Owner.String()),
   120  		sdk.NewAttribute(types.AttributeKeyPool, msg.PoolName),
   121  		sdk.NewAttribute(types.AttributeKeyWithdraw, withdrawAmount.String()),
   122  	))
   123  	return &sdk.Result{Events: ctx.EventManager().Events()}, nil
   124  }