diff --git a/CHANGELOG.md b/CHANGELOG.md index 978fbeac..495510a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,8 @@ Ref: https://keepachangelog.com/en/1.0.0/ - [792](https://github.com/persistenceOne/pstake-native/pull/792) Use GetHostChainFromHostDenom in ICA Transfer unsuccessfulAck instead of GetHostChainFromDelegatorAddress as Rewards account too uses ICA Transfer to autocompound +- [795](https://github.com/persistenceOne/pstake-native/pull/795) Reject zero weight validator LSM shares for + liquidstakeibc ## [v2.11.0] - 2024-03-12 diff --git a/x/liquidstakeibc/keeper/msg_server.go b/x/liquidstakeibc/keeper/msg_server.go index 8f20a9cb..459f0692 100644 --- a/x/liquidstakeibc/keeper/msg_server.go +++ b/x/liquidstakeibc/keeper/msg_server.go @@ -989,6 +989,10 @@ func (k msgServer) validateLiquidStakeLSMDeposit( return nil, nil, nil, errorsmod.Wrapf(types.ErrLSMValidatorInvalidState, "validator %s is not in the bonded state, it is in %s", operatorAddress, validator.Status) } + if validator.Weight.Equal(sdktypes.ZeroDec()) { + return nil, nil, nil, errorsmod.Wrapf(types.ErrValidatorNotFound, "validator %s is not in the validator set, weight is %s", operatorAddress, validator.Weight) + } + // check delegator has enough LSM tokens delegatorBalance := k.bankKeeper.GetBalance(ctx, delegatorAddress, delegation.Denom).Amount if delegatorBalance.LT(delegation.Amount) { diff --git a/x/liquidstakeibc/keeper/msg_server_test.go b/x/liquidstakeibc/keeper/msg_server_test.go index f8dac2b1..18b89830 100644 --- a/x/liquidstakeibc/keeper/msg_server_test.go +++ b/x/liquidstakeibc/keeper/msg_server_test.go @@ -3,6 +3,7 @@ package keeper_test import ( "context" "fmt" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "reflect" "testing" @@ -112,11 +113,32 @@ func (suite *IntegrationTestSuite) Test_msgServer_LiquidStakeLSM() { hc, found := pstakeapp.LiquidStakeIBCKeeper.GetHostChain(ctx, suite.chainB.ChainID) suite.Require().True(found) + inactiveValoperAddr := "persistencevaloper1wrxz49hjmq434zg072kl2ka3kqnau0ejs0vqpm" + pstakeapp.LiquidStakeIBCKeeper.SetHostChainValidator(ctx, hc, &types.Validator{ + OperatorAddress: inactiveValoperAddr, + Status: stakingtypes.BondStatusBonded, + Weight: sdk.ZeroDec(), + DelegatedAmount: sdk.OneInt(), + ExchangeRate: sdk.OneDec(), + UnbondingEpoch: 0, + Delegable: true, + }) + hc, found = pstakeapp.LiquidStakeIBCKeeper.GetHostChain(ctx, suite.chainB.ChainID) + suite.Require().True(found) lsmIbcDenom := ibctfrtypes.ParseDenomTrace( ibctfrtypes.GetPrefixedDenom(hc.PortId, hc.ChannelId, hc.Validators[0].OperatorAddress+"/1"), ).IBCDenom() + suite.Require().Equal(nil, transfertypes.ValidateIBCDenom(lsmIbcDenom)) + lsmIbcDenomZeroWeightTrace := ibctfrtypes.ParseDenomTrace( + ibctfrtypes.GetPrefixedDenom(hc.PortId, hc.ChannelId, inactiveValoperAddr+"/1"), + ) + lsmIbcDenomZeroWeight := lsmIbcDenomZeroWeightTrace.IBCDenom() + pstakeapp.TransferKeeper.SetDenomTrace(ctx, lsmIbcDenomZeroWeightTrace) + + suite.Require().Equal(nil, transfertypes.ValidateIBCDenom(lsmIbcDenomZeroWeight)) + type args struct { goCtx context.Context msg *types.MsgLiquidStakeLSM @@ -257,6 +279,21 @@ func (suite *IntegrationTestSuite) Test_msgServer_LiquidStakeLSM() { want: nil, wantErr: true, }, + { + name: "inactive validator", + args: args{ + goCtx: ctx, + msg: &types.MsgLiquidStakeLSM{ + DelegatorAddress: suite.chainA.SenderAccount.GetAddress().String(), + Delegations: sdk.NewCoins(sdk.NewCoin(lsmIbcDenomZeroWeight, sdk.NewInt(4))), + }, + chainActive: true, + lsmActive: true, + createSecondDeposit: true, + }, + want: nil, + wantErr: true, + }, } for _, tt := range tests {