mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-11-04 03:57:44 +00:00 
			
		
		
		
	Add derivative denom and kava value methods to liquid (#1303)
* Add IsDerivativeDenom and GetKavaForDerivatives methods to liquid * Add test case containing 2 different bkava denoms * Add doc to GetKavaForDerivatives * Remove logging statements, use keeper logger * Fix nil err use * Return error from GetKavaForDerivatives * Re-add ParseLiquidStakingTokenDenom * Add ParseLiquidStakingTokenDenom tests * Use DenomSeparator instead of str Co-authored-by: Ruaridh <rhuairahrighairidh@users.noreply.github.com> Co-authored-by: Ruaridh <rhuairahrighairidh@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									ceaed3f0e1
								
							
						
					
					
						commit
						ed116b24ba
					
				@ -2,7 +2,6 @@ package cli
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/spf13/cobra"
 | 
						"github.com/spf13/cobra"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -94,7 +93,7 @@ func getCmdBurnDerivative() *cobra.Command {
 | 
				
			|||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			valAddr, err := parseLiquidStakingTokenDenom(amount.Denom)
 | 
								valAddr, err := types.ParseLiquidStakingTokenDenom(amount.Denom)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return sdkerrors.Wrap(types.ErrInvalidDenom, err.Error())
 | 
									return sdkerrors.Wrap(types.ErrInvalidDenom, err.Error())
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@ -107,16 +106,3 @@ func getCmdBurnDerivative() *cobra.Command {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
// parseLiquidStakingTokenDenom extracts a validator address from a derivative denom.
 | 
					 | 
				
			||||||
func parseLiquidStakingTokenDenom(denom string) (sdk.ValAddress, error) {
 | 
					 | 
				
			||||||
	elements := strings.Split(denom, types.DenomSeparator)
 | 
					 | 
				
			||||||
	if len(elements) != 2 {
 | 
					 | 
				
			||||||
		return nil, fmt.Errorf("cannot parse denom %s", denom)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	addr, err := sdk.ValAddressFromBech32(elements[1])
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return addr, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,8 @@
 | 
				
			|||||||
package keeper
 | 
					package keeper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
						sdk "github.com/cosmos/cosmos-sdk/types"
 | 
				
			||||||
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
 | 
						sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -97,6 +99,42 @@ func (k Keeper) GetLiquidStakingTokenDenom(valAddr sdk.ValAddress) string {
 | 
				
			|||||||
	return types.GetLiquidStakingTokenDenom(k.derivativeDenom, valAddr)
 | 
						return types.GetLiquidStakingTokenDenom(k.derivativeDenom, valAddr)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsDerivativeDenom returns true if the denom is a valid derivative denom and
 | 
				
			||||||
 | 
					// corresponds to a valid validator.
 | 
				
			||||||
 | 
					func (k Keeper) IsDerivativeDenom(ctx sdk.Context, denom string) bool {
 | 
				
			||||||
 | 
						valAddr, err := types.ParseLiquidStakingTokenDenom(denom)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, found := k.stakingKeeper.GetValidator(ctx, valAddr)
 | 
				
			||||||
 | 
						return found
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetKavaForDerivatives returns the total amount of the provided derivatives
 | 
				
			||||||
 | 
					// in Kava accounting for the specific share prices.
 | 
				
			||||||
 | 
					func (k Keeper) GetKavaForDerivatives(ctx sdk.Context, coins sdk.Coins) (sdk.Int, error) {
 | 
				
			||||||
 | 
						totalKava := sdk.ZeroInt()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, coin := range coins {
 | 
				
			||||||
 | 
							valAddr, err := types.ParseLiquidStakingTokenDenom(coin.Denom)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return sdk.Int{}, fmt.Errorf("invalid derivative denom: %w", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							validator, found := k.stakingKeeper.GetValidator(ctx, valAddr)
 | 
				
			||||||
 | 
							if !found {
 | 
				
			||||||
 | 
								return sdk.Int{}, fmt.Errorf("invalid derivative denom %s: validator not found", coin.Denom)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// bkava is 1:1 to delegation shares
 | 
				
			||||||
 | 
							valTokens := validator.TokensFromSharesTruncated(coin.Amount.ToDec())
 | 
				
			||||||
 | 
							totalKava = totalKava.Add(valTokens.TruncateInt())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return totalKava, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (k Keeper) mintCoins(ctx sdk.Context, receiver sdk.AccAddress, amount sdk.Coins) error {
 | 
					func (k Keeper) mintCoins(ctx sdk.Context, receiver sdk.AccAddress, amount sdk.Coins) error {
 | 
				
			||||||
	if err := k.bankKeeper.MintCoins(ctx, types.ModuleAccountName, amount); err != nil {
 | 
						if err := k.bankKeeper.MintCoins(ctx, types.ModuleAccountName, amount); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
 | 
				
			|||||||
@ -314,3 +314,158 @@ func (suite *KeeperTestSuite) TestMintDerivative() {
 | 
				
			|||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *KeeperTestSuite) TestIsDerivativeDenom() {
 | 
				
			||||||
 | 
						_, addrs := app.GeneratePrivKeyAddressPairs(5)
 | 
				
			||||||
 | 
						valAccAddr1, delegator, valAccAddr2 := addrs[0], addrs[1], addrs[2]
 | 
				
			||||||
 | 
						valAddr1 := sdk.ValAddress(valAccAddr1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Validator addr that has **not** delegated anything
 | 
				
			||||||
 | 
						valAddr2 := sdk.ValAddress(valAccAddr2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						initialBalance := i(1e9)
 | 
				
			||||||
 | 
						vestedBalance := i(500e6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						suite.CreateAccountWithAddress(valAccAddr1, suite.NewBondCoins(initialBalance))
 | 
				
			||||||
 | 
						suite.CreateVestingAccountWithAddress(delegator, suite.NewBondCoins(initialBalance), suite.NewBondCoins(vestedBalance))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						suite.CreateNewUnbondedValidator(valAddr1, initialBalance)
 | 
				
			||||||
 | 
						suite.CreateDelegation(valAddr1, delegator, initialBalance)
 | 
				
			||||||
 | 
						staking.EndBlocker(suite.Ctx, suite.StakingKeeper)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						testCases := []struct {
 | 
				
			||||||
 | 
							name        string
 | 
				
			||||||
 | 
							denom       string
 | 
				
			||||||
 | 
							wantIsDenom bool
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name:        "valid derivative denom",
 | 
				
			||||||
 | 
								denom:       suite.Keeper.GetLiquidStakingTokenDenom(valAddr1),
 | 
				
			||||||
 | 
								wantIsDenom: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name:        "invalid - undelegated validator addr",
 | 
				
			||||||
 | 
								denom:       suite.Keeper.GetLiquidStakingTokenDenom(valAddr2),
 | 
				
			||||||
 | 
								wantIsDenom: false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name:        "invalid - invalid val addr",
 | 
				
			||||||
 | 
								denom:       "bkava-asdfasdf",
 | 
				
			||||||
 | 
								wantIsDenom: false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name:        "invalid - ukava",
 | 
				
			||||||
 | 
								denom:       "ukava",
 | 
				
			||||||
 | 
								wantIsDenom: false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name:        "invalid - plain bkava",
 | 
				
			||||||
 | 
								denom:       "bkava",
 | 
				
			||||||
 | 
								wantIsDenom: false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name:        "invalid - bkava prefix",
 | 
				
			||||||
 | 
								denom:       "bkava-",
 | 
				
			||||||
 | 
								wantIsDenom: false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tc := range testCases {
 | 
				
			||||||
 | 
							suite.Run(tc.name, func() {
 | 
				
			||||||
 | 
								isDenom := suite.Keeper.IsDerivativeDenom(suite.Ctx, tc.denom)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								suite.Require().Equal(tc.wantIsDenom, isDenom)
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *KeeperTestSuite) TestGetKavaForDerivatives() {
 | 
				
			||||||
 | 
						_, addrs := app.GeneratePrivKeyAddressPairs(5)
 | 
				
			||||||
 | 
						valAccAddr1, delegator, valAccAddr2, valAccAddr3 := addrs[0], addrs[1], addrs[2], addrs[3]
 | 
				
			||||||
 | 
						valAddr1 := sdk.ValAddress(valAccAddr1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Validator addr that has **not** delegated anything
 | 
				
			||||||
 | 
						valAddr2 := sdk.ValAddress(valAccAddr2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						valAddr3 := sdk.ValAddress(valAccAddr3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						initialBalance := i(1e9)
 | 
				
			||||||
 | 
						vestedBalance := i(500e6)
 | 
				
			||||||
 | 
						delegateAmount := i(100e6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						suite.CreateAccountWithAddress(valAccAddr1, suite.NewBondCoins(initialBalance))
 | 
				
			||||||
 | 
						suite.CreateVestingAccountWithAddress(delegator, suite.NewBondCoins(initialBalance), suite.NewBondCoins(vestedBalance))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						suite.CreateNewUnbondedValidator(valAddr1, initialBalance)
 | 
				
			||||||
 | 
						suite.CreateDelegation(valAddr1, delegator, delegateAmount)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						suite.CreateAccountWithAddress(valAccAddr3, suite.NewBondCoins(initialBalance))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						suite.CreateNewUnbondedValidator(valAddr3, initialBalance)
 | 
				
			||||||
 | 
						suite.CreateDelegation(valAddr3, delegator, delegateAmount)
 | 
				
			||||||
 | 
						staking.EndBlocker(suite.Ctx, suite.StakingKeeper)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						suite.SlashValidator(valAddr3, d("0.05"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err := suite.Keeper.MintDerivative(suite.Ctx, delegator, valAddr1, suite.NewBondCoin(delegateAmount))
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						testCases := []struct {
 | 
				
			||||||
 | 
							name           string
 | 
				
			||||||
 | 
							derivatives    sdk.Coins
 | 
				
			||||||
 | 
							wantKavaAmount sdk.Int
 | 
				
			||||||
 | 
							err            error
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "valid derivative denom",
 | 
				
			||||||
 | 
								derivatives: sdk.NewCoins(
 | 
				
			||||||
 | 
									sdk.NewCoin(suite.Keeper.GetLiquidStakingTokenDenom(valAddr1), vestedBalance),
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
								wantKavaAmount: vestedBalance,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "valid - slashed validator",
 | 
				
			||||||
 | 
								derivatives: sdk.NewCoins(
 | 
				
			||||||
 | 
									sdk.NewCoin(suite.Keeper.GetLiquidStakingTokenDenom(valAddr3), vestedBalance),
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
								// vestedBalance * 95%
 | 
				
			||||||
 | 
								wantKavaAmount: vestedBalance.Mul(sdk.NewInt(95)).Quo(sdk.NewInt(100)),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "valid - sum",
 | 
				
			||||||
 | 
								derivatives: sdk.NewCoins(
 | 
				
			||||||
 | 
									sdk.NewCoin(suite.Keeper.GetLiquidStakingTokenDenom(valAddr3), vestedBalance),
 | 
				
			||||||
 | 
									sdk.NewCoin(suite.Keeper.GetLiquidStakingTokenDenom(valAddr1), vestedBalance),
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
								// vestedBalance + (vestedBalance * 95%)
 | 
				
			||||||
 | 
								wantKavaAmount: vestedBalance.Mul(sdk.NewInt(95)).Quo(sdk.NewInt(100)).Add(vestedBalance),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "invalid - undelegated validator address denom",
 | 
				
			||||||
 | 
								derivatives: sdk.NewCoins(
 | 
				
			||||||
 | 
									sdk.NewCoin(suite.Keeper.GetLiquidStakingTokenDenom(valAddr2), vestedBalance),
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
								err: fmt.Errorf("invalid derivative denom %s: validator not found", suite.Keeper.GetLiquidStakingTokenDenom(valAddr2)),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "invalid - denom",
 | 
				
			||||||
 | 
								derivatives: sdk.NewCoins(
 | 
				
			||||||
 | 
									sdk.NewCoin("kava", vestedBalance),
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
								err: fmt.Errorf("invalid derivative denom: cannot parse denom kava"),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tc := range testCases {
 | 
				
			||||||
 | 
							suite.Run(tc.name, func() {
 | 
				
			||||||
 | 
								kavaAmount, err := suite.Keeper.GetKavaForDerivatives(suite.Ctx, tc.derivatives)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if tc.err != nil {
 | 
				
			||||||
 | 
									suite.Require().Error(err)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									suite.Require().NoError(err)
 | 
				
			||||||
 | 
									suite.Require().Equal(tc.wantKavaAmount, kavaAmount)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@ package types
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
						sdk "github.com/cosmos/cosmos-sdk/types"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@ -24,3 +25,22 @@ const (
 | 
				
			|||||||
func GetLiquidStakingTokenDenom(bondDenom string, valAddr sdk.ValAddress) string {
 | 
					func GetLiquidStakingTokenDenom(bondDenom string, valAddr sdk.ValAddress) string {
 | 
				
			||||||
	return fmt.Sprintf("%s%s%s", bondDenom, DenomSeparator, valAddr.String())
 | 
						return fmt.Sprintf("%s%s%s", bondDenom, DenomSeparator, valAddr.String())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ParseLiquidStakingTokenDenom extracts a validator address from a derivative denom.
 | 
				
			||||||
 | 
					func ParseLiquidStakingTokenDenom(denom string) (sdk.ValAddress, error) {
 | 
				
			||||||
 | 
						elements := strings.Split(denom, DenomSeparator)
 | 
				
			||||||
 | 
						if len(elements) != 2 {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("cannot parse denom %s", denom)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if elements[0] != DefaultDerivativeDenom {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("invalid denom prefix, expected %s, got %s", DefaultDerivativeDenom, elements[0])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						addr, err := sdk.ValAddressFromBech32(elements[1])
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("invalid denom validator address: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return addr, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										56
									
								
								x/liquid/types/key_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								x/liquid/types/key_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					package types_test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sdk "github.com/cosmos/cosmos-sdk/types"
 | 
				
			||||||
 | 
						"github.com/kava-labs/kava/app"
 | 
				
			||||||
 | 
						"github.com/kava-labs/kava/x/liquid/types"
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/require"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestParseLiquidStakingTokenDenom(t *testing.T) {
 | 
				
			||||||
 | 
						config := sdk.GetConfig()
 | 
				
			||||||
 | 
						app.SetBech32AddressPrefixes(config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							name        string
 | 
				
			||||||
 | 
							giveDenom   string
 | 
				
			||||||
 | 
							wantAddress sdk.ValAddress
 | 
				
			||||||
 | 
							wantErr     error
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name:        "valid denom",
 | 
				
			||||||
 | 
								giveDenom:   "bkava-kavavaloper1ze7y9qwdddejmy7jlw4cymqqlt2wh05y6cpt5a",
 | 
				
			||||||
 | 
								wantAddress: mustValAddressFromBech32("kavavaloper1ze7y9qwdddejmy7jlw4cymqqlt2wh05y6cpt5a"),
 | 
				
			||||||
 | 
								wantErr:     nil,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name:        "invalid prefix",
 | 
				
			||||||
 | 
								giveDenom:   "ukava-kavavaloper1ze7y9qwdddejmy7jlw4cymqqlt2wh05y6cpt5a",
 | 
				
			||||||
 | 
								wantAddress: mustValAddressFromBech32("kavavaloper1ze7y9qwdddejmy7jlw4cymqqlt2wh05y6cpt5a"),
 | 
				
			||||||
 | 
								wantErr:     fmt.Errorf("invalid denom prefix, expected %s, got %s", types.DefaultDerivativeDenom, "ukava"),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name:        "invalid validator address",
 | 
				
			||||||
 | 
								giveDenom:   "bkava-kavavaloper1ze7y9qw",
 | 
				
			||||||
 | 
								wantAddress: sdk.ValAddress{},
 | 
				
			||||||
 | 
								wantErr:     fmt.Errorf("invalid denom validator address: decoding bech32 failed: invalid checksum"),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tt := range tests {
 | 
				
			||||||
 | 
							t.Run(tt.name, func(t *testing.T) {
 | 
				
			||||||
 | 
								addr, err := types.ParseLiquidStakingTokenDenom(tt.giveDenom)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if tt.wantErr != nil {
 | 
				
			||||||
 | 
									require.Error(t, err)
 | 
				
			||||||
 | 
									require.Contains(t, err.Error(), tt.wantErr.Error())
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									require.NoError(t, err)
 | 
				
			||||||
 | 
									require.Equal(t, tt.wantAddress, addr)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user