Skip to content

Commit

Permalink
fix: implement anti-spam for proposals in gov
Browse files Browse the repository at this point in the history
  • Loading branch information
kamuikatsurgi committed Jan 16, 2025
1 parent 67bf9d5 commit cf29397
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 7 deletions.
21 changes: 14 additions & 7 deletions x/gov/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ func EndBlocker(ctx sdk.Context, keeper *keeper.Keeper) error {
return false, err
}

// TODO HV2: https://polygon.atlassian.net/browse/POS-2755
err = keeper.RefundAndDeleteDeposits(ctx, proposal.Id) // refund deposit if proposal got removed without getting 100% of the proposal
// Distribute the deposits if the proposal got removed without getting 100% of the proposal
err = keeper.DistributeAndDeleteDeposits(ctx, proposal.Id)
if err != nil {
return false, err
}
Expand Down Expand Up @@ -135,10 +135,17 @@ func EndBlocker(ctx sdk.Context, keeper *keeper.Keeper) error {
return false, err
}

// HV2: heimdall refunds and deletes deposits in all cases of proposal failures, without caring about burnDeposits
err = keeper.RefundAndDeleteDeposits(ctx, proposal.Id)
if err != nil {
return false, err
// HV2: heimdall distributes and deletes deposits in all cases of proposal failures, without caring about burnDeposits
if passes {
err = keeper.RefundAndDeleteDeposits(ctx, proposal.Id)
if err != nil {
return false, err
}
} else {
err = keeper.DistributeAndDeleteDeposits(ctx, proposal.Id)
if err != nil {
return false, err
}
}

// If an expedited proposal fails, we do not want to update
Expand Down Expand Up @@ -315,7 +322,7 @@ func failUnsupportedProposal(
return err
}

if err := keeper.RefundAndDeleteDeposits(ctx, proposal.Id); err != nil {
if err := keeper.DistributeAndDeleteDeposits(ctx, proposal.Id); err != nil {
return err
}

Expand Down
76 changes: 76 additions & 0 deletions x/gov/keeper/deposit.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"cosmossdk.io/errors"
sdkmath "cosmossdk.io/math"

stakeTypes "github.com/0xPolygon/heimdall-v2/x/stake/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
Expand Down Expand Up @@ -285,6 +286,81 @@ func (keeper Keeper) RefundAndDeleteDeposits(ctx context.Context, proposalID uin
})
}

// DistributeAndDeleteDeposits distributes the deposits evenly among all the active validators and deletes the deposits on a specific proposal.
func (keeper Keeper) DistributeAndDeleteDeposits(ctx context.Context, proposalID uint64) error {
var validatorAddresses []sdk.AccAddress

err := keeper.sk.IterateCurrentValidatorsAndApplyFn(ctx, func(validator stakeTypes.Validator) bool {
validatorAddr, err := sdk.AccAddressFromHex(validator.Signer)
if err != nil {
return true
}
validatorAddresses = append(validatorAddresses, validatorAddr)
return false
})
if err != nil {
return err
}

numValidators := len(validatorAddresses)
if numValidators == 0 {
return fmt.Errorf("no current validators available")
}

deposits, err := keeper.GetDeposits(ctx, proposalID)
if err != nil {
return err
}

var totalDeposits sdk.Coins
var amountPerValidator sdk.Coins

for _, deposit := range deposits {
depositerAddress, err := keeper.authKeeper.AddressCodec().StringToBytes(deposit.Depositor)
if err != nil {
return err
}

totalDeposits = totalDeposits.Add(deposit.Amount...)

for _, coin := range deposit.Amount {
amountPerValidatorPerCoin := sdkmath.LegacyNewDecFromInt(coin.Amount).QuoInt64(int64(numValidators)).TruncateInt()
amountPerValidator = amountPerValidator.Add(
sdk.NewCoin(
coin.Denom,
amountPerValidatorPerCoin,
),
)
}

err = keeper.Deposits.Remove(ctx, collections.Join(deposit.ProposalId, sdk.AccAddress(depositerAddress)))
if err != nil {
return err
}
}

for _, validator := range validatorAddresses {
err = keeper.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, validator, amountPerValidator)
if err != nil {
return err
}
}

// Calculate any remaining amount due to truncating issues
usedAmount := amountPerValidator.MulInt(sdkmath.NewInt(int64(numValidators)))
remainingAmount, _ := totalDeposits.SafeSub(usedAmount...)

if !remainingAmount.IsZero() {
// Send remaining amount to the first validator
err = keeper.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, validatorAddresses[0], remainingAmount)
if err != nil {
return err
}
}

return err
}

// validateInitialDeposit validates if initial deposit is greater than or equal to the minimum
// required at the time of proposal submission. This threshold amount is determined by
// the deposit parameters. Returns nil on success, error otherwise.
Expand Down

0 comments on commit cf29397

Please sign in to comment.