github.com/KiraCore/sekai@v0.3.43/x/tokens/keeper/rate.go (about)

     1  package keeper
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/cosmos/cosmos-sdk/store/prefix"
     9  	sdk "github.com/cosmos/cosmos-sdk/types"
    10  
    11  	"github.com/KiraCore/sekai/x/tokens/types"
    12  )
    13  
    14  // GetTokenRate returns a token rate
    15  func (k Keeper) GetTokenRate(ctx sdk.Context, denom string) *types.TokenRate {
    16  	prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), PrefixKeyTokenRate)
    17  	bz := prefixStore.Get([]byte(denom))
    18  	if bz == nil {
    19  		return nil
    20  	}
    21  
    22  	rate := new(types.TokenRate)
    23  	k.cdc.MustUnmarshal(bz, rate)
    24  
    25  	return rate
    26  }
    27  
    28  // GetAllTokenRates returns all list of token rate
    29  func (k Keeper) GetAllTokenRates(ctx sdk.Context) []*types.TokenRate {
    30  	var tokenRates []*types.TokenRate
    31  
    32  	// get iterator for token rates
    33  	store := ctx.KVStore(k.storeKey)
    34  	iterator := sdk.KVStorePrefixIterator(store, PrefixKeyTokenRate)
    35  	defer iterator.Close()
    36  
    37  	for ; iterator.Valid(); iterator.Next() {
    38  		denom := strings.TrimPrefix(string(iterator.Key()), string(PrefixKeyTokenRate))
    39  		tokenRate := k.GetTokenRate(ctx, denom)
    40  		if tokenRate != nil {
    41  			tokenRates = append(tokenRates, tokenRate)
    42  		}
    43  	}
    44  	return tokenRates
    45  }
    46  
    47  // GetTokenRatesByDenom returns all list of token rate
    48  func (k Keeper) GetTokenRatesByDenom(ctx sdk.Context, denoms []string) map[string]*types.TokenRate {
    49  	// get iterator for token aliases
    50  	store := ctx.KVStore(k.storeKey)
    51  	tokenRatesMap := make(map[string]*types.TokenRate)
    52  
    53  	for _, denom := range denoms {
    54  		denomTokenStoreID := append([]byte(PrefixKeyTokenRate), []byte(denom)...)
    55  
    56  		if store.Has(denomTokenStoreID) {
    57  			tokenRate := k.GetTokenRate(ctx, denom)
    58  			tokenRatesMap[denom] = tokenRate
    59  		}
    60  	}
    61  	return tokenRatesMap
    62  }
    63  
    64  // UpsertTokenRate upsert a token rate to the registry
    65  func (k Keeper) UpsertTokenRate(ctx sdk.Context, rate types.TokenRate) error {
    66  	store := ctx.KVStore(k.storeKey)
    67  	// we use denom of TokenRate as an ID inside KVStore storage
    68  	tokenRateStoreID := append([]byte(PrefixKeyTokenRate), []byte(rate.Denom)...)
    69  	if rate.Denom == k.DefaultDenom(ctx) && store.Has(tokenRateStoreID) {
    70  		return errors.New("bond denom rate is read-only")
    71  	}
    72  
    73  	store.Set(tokenRateStoreID, k.cdc.MustMarshal(&rate))
    74  
    75  	totalRewardsCap := sdk.ZeroDec()
    76  	rates := k.GetAllTokenRates(ctx)
    77  	for _, rate := range rates {
    78  		totalRewardsCap = totalRewardsCap.Add(rate.StakeCap)
    79  	}
    80  	if totalRewardsCap.GT(sdk.OneDec()) {
    81  		return types.ErrTotalRewardsCapExceeds100Percent
    82  	}
    83  	return nil
    84  }
    85  
    86  // DeleteTokenRate delete token denom by denom
    87  func (k Keeper) DeleteTokenRate(ctx sdk.Context, denom string) error {
    88  	store := ctx.KVStore(k.storeKey)
    89  	// we use symbol of DeleteTokenRate as an ID inside KVStore storage
    90  	tokenRateStoreID := append([]byte(PrefixKeyTokenRate), []byte(denom)...)
    91  
    92  	if !store.Has(tokenRateStoreID) {
    93  		return fmt.Errorf("no rate registry is available for %s denom", denom)
    94  	}
    95  
    96  	store.Delete(tokenRateStoreID)
    97  	return nil
    98  }