Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(staking): align min self delegation with min delegation #214

Merged
merged 2 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 49 additions & 45 deletions client/x/evmstaking/keeper/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,53 +78,57 @@ func (k Keeper) ProcessCreateValidator(ctx context.Context, ev *bindings.IPToken
}
skeeperMsgServer := skeeper.NewMsgServerImpl(evmstakingSKeeper)

_, err = k.stakingKeeper.GetValidator(ctx, validatorAddr)
if err != nil {
if _, err = k.stakingKeeper.GetValidator(ctx, validatorAddr); err == nil {
// TODO(rayden): refund
return errors.New("validator already exists")
} else if !errors.Is(err, stypes.ErrNoValidatorFound) {
// Either the validator does not exist, or unknown error.
if !errors.Is(err, stypes.ErrNoValidatorFound) {
return errors.Wrap(err, "get validator")
}

moniker := ev.Moniker
if moniker == "validator" {
moniker = validatorAddr.String() // use validator address as moniker if not provided (ie. "validator")
}

var tokenType stypes.TokenType
switch ev.SupportsUnlocked {
case uint8(stypes.TokenType_LOCKED):
tokenType = stypes.TokenType_LOCKED
case uint8(stypes.TokenType_UNLOCKED):
tokenType = stypes.TokenType_UNLOCKED
default:
return errors.New("invalid token type")
}

// Validator does not exist, create validator with self-delegation.
msg, err := stypes.NewMsgCreateValidator(
validatorAddr.String(),
validatorPubkey,
amountCoin,
stypes.Description{Moniker: moniker},
stypes.NewCommissionRates(
// Divide these decimals by 100 to convert from basis points to decimal. Will cut off decimal as the rates are integers.
math.LegacyNewDec(int64(ev.CommissionRate)).Quo(math.LegacyNewDec(10000)),
math.LegacyNewDec(int64(ev.MaxCommissionRate)).Quo(math.LegacyNewDec(10000)),
math.LegacyNewDec(int64(ev.MaxCommissionChangeRate)).Quo(math.LegacyNewDec(10000)),
),
math.NewInt(1), // Stub out minimum self delegation for now, just use 1.
tokenType,
)
if err != nil {
return errors.Wrap(err, "create validator message")
}

_, err = skeeperMsgServer.CreateValidator(ctx, msg)
if err != nil {
return errors.Wrap(err, "create validator")
}
return errors.Wrap(err, "get validator")
}

moniker := ev.Moniker
if moniker == "" {
moniker = validatorAddr.String() // use validator address as moniker if not provided
}

var tokenType stypes.TokenType
switch ev.SupportsUnlocked {
case uint8(stypes.TokenType_LOCKED):
tokenType = stypes.TokenType_LOCKED
case uint8(stypes.TokenType_UNLOCKED):
tokenType = stypes.TokenType_UNLOCKED
default:
return errors.New("invalid token type")
}

minSelfDelegation, err := k.stakingKeeper.MinDelegation(ctx)
if err != nil {
return errors.Wrap(err, "get min self delegation")
}

// Validator does not exist, create validator with self-delegation.
msg, err := stypes.NewMsgCreateValidator(
validatorAddr.String(),
validatorPubkey,
amountCoin,
stypes.Description{Moniker: moniker},
stypes.NewCommissionRates(
// Divide these decimals by 100 to convert from basis points to decimal. Will cut off decimal as the rates are integers.
ezreal1997 marked this conversation as resolved.
Show resolved Hide resolved
math.LegacyNewDec(int64(ev.CommissionRate)).Quo(math.LegacyNewDec(10000)),
math.LegacyNewDec(int64(ev.MaxCommissionRate)).Quo(math.LegacyNewDec(10000)),
math.LegacyNewDec(int64(ev.MaxCommissionChangeRate)).Quo(math.LegacyNewDec(10000)),
),
minSelfDelegation, // make minimum self delegation align with minimum delegation amount
tokenType,
)
if err != nil {
return errors.Wrap(err, "create validator message")
}

_, err = skeeperMsgServer.CreateValidator(ctx, msg)
if err != nil {
return errors.Wrap(err, "create validator")
}
// TODO(rayden): refund

return nil
}
Expand Down
3 changes: 3 additions & 0 deletions client/x/evmstaking/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"cosmossdk.io/core/address"
corestore "cosmossdk.io/core/store"
"cosmossdk.io/math"

abci "github.com/cometbft/cometbft/abci/types"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -65,6 +66,8 @@ type StakingKeeper interface {

EndBlocker(ctx context.Context) ([]abci.ValidatorUpdate, error)
EndBlockerWithUnbondedEntries(ctx context.Context) ([]abci.ValidatorUpdate, []stakingtypes.UnbondedEntry, error)

MinDelegation(ctx context.Context) (math.Int, error)
}

// SlashingKeeper defines the expected interface for the slashing module.
Expand Down
Loading