Skip to content

Commit

Permalink
Merge pull request #203 from yihuang/release/v0.46.x
Browse files Browse the repository at this point in the history
Problem: GHSA-86h5-xcpx-cfqc is not merged
  • Loading branch information
yihuang authored Feb 29, 2024
2 parents 7799bba + 3ec552f commit 9a8efd8
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ Ref: https://keepachangelog.com/en/1.0.0/

# Changelog

* (x/staking) Fix a possible bypass of delagator slashing: [GHSA-86h5-xcpx-cfqc](https://github.com/cosmos/cosmos-sdk/security/advisories/GHSA-86h5-xcpx-cfqc)

## [v0.46.16](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.46.16) - 2023-11-07

EOL notice. This is the last release of the `v0.46.x` line. Per this version, the v0.46.x line reached its end-of-life.
Expand Down
2 changes: 1 addition & 1 deletion simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ func NewSimApp(
appCodec, keys[banktypes.StoreKey], app.AccountKeeper, app.GetSubspace(banktypes.ModuleName), app.ModuleAccountAddrs(),
)
stakingKeeper := stakingkeeper.NewKeeper(
appCodec, keys[stakingtypes.StoreKey], app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName),
appCodec, keys[stakingtypes.StoreKey], app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName), 0,
)
app.MintKeeper = mintkeeper.NewKeeper(
appCodec, keys[minttypes.StoreKey], app.GetSubspace(minttypes.ModuleName), &stakingKeeper,
Expand Down
1 change: 1 addition & 0 deletions x/auth/migrations/v043/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,7 @@ func createValidator(t *testing.T, ctx sdk.Context, app *simapp.SimApp, powers i
app.AccountKeeper,
app.BankKeeper,
app.GetSubspace(stakingtypes.ModuleName),
0,
)

val1, err := stakingtypes.NewValidator(valAddrs[0], pks[0], stakingtypes.Description{})
Expand Down
1 change: 1 addition & 0 deletions x/gov/keeper/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ func createValidators(t *testing.T, ctx sdk.Context, app *simapp.SimApp, powers
app.AccountKeeper,
app.BankKeeper,
app.GetSubspace(stakingtypes.ModuleName),
0,
)

val1, err := stakingtypes.NewValidator(valAddrs[0], pks[0], stakingtypes.Description{})
Expand Down
1 change: 1 addition & 0 deletions x/staking/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func getBaseSimappWithCustomKeeper(t *testing.T) (*codec.LegacyAmino, *simapp.Si
app.AccountKeeper,
app.BankKeeper,
app.GetSubspace(types.ModuleName),
0,
)
app.StakingKeeper.SetParams(ctx, types.DefaultParams())

Expand Down
1 change: 1 addition & 0 deletions x/staking/keeper/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func createTestInput(t *testing.T) (*codec.LegacyAmino, *simapp.SimApp, sdk.Cont
app.AccountKeeper,
app.BankKeeper,
app.GetSubspace(types.ModuleName),
0,
)
return app.LegacyAmino(), app, ctx
}
Expand Down
1 change: 1 addition & 0 deletions x/staking/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,7 @@ func createValidators(t *testing.T, ctx sdk.Context, app *simapp.SimApp, powers
app.AccountKeeper,
app.BankKeeper,
app.GetSubspace(types.ModuleName),
0,
)

val1 := teststaking.NewValidator(t, valAddrs[0], pks[0])
Expand Down
5 changes: 5 additions & 0 deletions x/staking/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,15 @@ type Keeper struct {
bankKeeper types.BankKeeper
hooks types.StakingHooks
paramstore paramtypes.Subspace

hardForkHeight int64
}

// NewKeeper creates a new staking Keeper instance
func NewKeeper(
cdc codec.BinaryCodec, key storetypes.StoreKey, ak types.AccountKeeper, bk types.BankKeeper,
ps paramtypes.Subspace,
hardForkHeight int64,
) Keeper {
// set KeyTable if it has not already been set
if !ps.HasKeyTable() {
Expand All @@ -55,6 +58,8 @@ func NewKeeper(
bankKeeper: bk,
paramstore: ps,
hooks: nil,

hardForkHeight: hardForkHeight,
}
}

Expand Down
49 changes: 44 additions & 5 deletions x/staking/keeper/slash.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,17 +250,56 @@ func (k Keeper) SlashRedelegation(ctx sdk.Context, srcValidator types.Validator,
slashAmount := slashAmountDec.TruncateInt()
totalSlashAmount = totalSlashAmount.Add(slashAmount)

valDstAddr, err := sdk.ValAddressFromBech32(redelegation.ValidatorDstAddress)
if err != nil {
panic(err)
}

if k.hardForkHeight >= ctx.BlockHeight() {
// Handle undelegation after redelegation
// Prioritize slashing unbondingDelegation than delegation
unbondingDelegation, found := k.GetUnbondingDelegation(ctx, sdk.MustAccAddressFromBech32(redelegation.DelegatorAddress), valDstAddr)
if found {
for i, entry := range unbondingDelegation.Entries {
// slash with the amount of `slashAmount` if possible, else slash all unbonding token
unbondingSlashAmount := math.MinInt(slashAmount, entry.Balance)

switch {
// There's no token to slash
case unbondingSlashAmount.IsZero():
continue
// If unbonding started before this height, stake didn't contribute to infraction
case entry.CreationHeight < infractionHeight:
continue
// Unbonding delegation no longer eligible for slashing, skip it
case entry.IsMature(now):
continue
// Slash the unbonding delegation
default:
// update remaining slashAmount
slashAmount = slashAmount.Sub(unbondingSlashAmount)

notBondedBurnedAmount = notBondedBurnedAmount.Add(unbondingSlashAmount)
entry.Balance = entry.Balance.Sub(unbondingSlashAmount)
unbondingDelegation.Entries[i] = entry
k.SetUnbondingDelegation(ctx, unbondingDelegation)
}
}
}

if slashAmount.IsZero() {
continue
}
}

// Slash the moved delegation

// Unbond from target validator
sharesToUnbond := slashFactor.Mul(entry.SharesDst)
if sharesToUnbond.IsZero() {
continue
}

valDstAddr, err := sdk.ValAddressFromBech32(redelegation.ValidatorDstAddress)
if err != nil {
panic(err)
}

delegatorAddress := sdk.MustAccAddressFromBech32(redelegation.DelegatorAddress)

delegation, found := k.GetDelegation(ctx, delegatorAddress, valDstAddr)
Expand Down

0 comments on commit 9a8efd8

Please sign in to comment.