From 4e4cca1a24de55dde893e014e27d58ca17e2abe5 Mon Sep 17 00:00:00 2001 From: Ragnar Date: Mon, 12 May 2025 21:14:24 +0200 Subject: [PATCH] fix(x/feegrant): prevent duplicate grants in genesis state (#24134) Co-authored-by: Alex | Interchain Labs --- x/feegrant/CHANGELOG.md | 4 ++++ x/feegrant/genesis.go | 12 ++++++++++ x/feegrant/genesis_test.go | 46 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 x/feegrant/genesis_test.go diff --git a/x/feegrant/CHANGELOG.md b/x/feegrant/CHANGELOG.md index 3e84c2b6e7..0d1ddb3555 100644 --- a/x/feegrant/CHANGELOG.md +++ b/x/feegrant/CHANGELOG.md @@ -25,6 +25,10 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [Unreleased] +### Bug Fixes + +* [#24134](https://github.com/cosmos/cosmos-sdk/pull/24134) Add validation to prevent duplicate fee grants in genesis state. + ## [v0.2.0](https://github.com/cosmos/cosmos-sdk/releases/tag/x/feegrant/v0.2.0) - 2025-04-24 * SDK v0.53.x support. diff --git a/x/feegrant/genesis.go b/x/feegrant/genesis.go index 83b29baeb8..191b7be30d 100644 --- a/x/feegrant/genesis.go +++ b/x/feegrant/genesis.go @@ -1,6 +1,8 @@ package feegrant import ( + "fmt" + "github.com/cosmos/cosmos-sdk/codec/types" ) @@ -15,7 +17,17 @@ func NewGenesisState(entries []Grant) *GenesisState { // ValidateGenesis ensures all grants in the genesis state are valid func ValidateGenesis(data GenesisState) error { + // Check for duplicate grants by (granter, grantee) pair + seen := make(map[string]struct{}) + for _, f := range data.Allowances { + // Create a unique key for (granter, grantee) pair using a delimiter + key := fmt.Sprintf("%s|%s", f.Granter, f.Grantee) + if _, exists := seen[key]; exists { + return fmt.Errorf("duplicate feegrant found from granter %q to grantee %q", f.Granter, f.Grantee) + } + seen[key] = struct{}{} + grant, err := f.GetGrant() if err != nil { return err diff --git a/x/feegrant/genesis_test.go b/x/feegrant/genesis_test.go new file mode 100644 index 0000000000..6c63370960 --- /dev/null +++ b/x/feegrant/genesis_test.go @@ -0,0 +1,46 @@ +package feegrant + +import ( + "testing" + + "gotest.tools/v3/assert" + + "cosmossdk.io/math" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func TestDuplicateGrantsInGenesis(t *testing.T) { + // Create dummy addresses for test + granter := sdk.AccAddress("granter_address____").String() + grantee := sdk.AccAddress("grantee_address____").String() + + // Create a BasicAllowance for testing + allowance := &BasicAllowance{ + SpendLimit: sdk.NewCoins(sdk.NewCoin("foo", math.NewInt(100))), + } + + any, err := codectypes.NewAnyWithValue(allowance) + assert.NilError(t, err) + + // Create Genesis state with duplicate allowances + genesisState := &GenesisState{ + Allowances: []Grant{ + { + Granter: granter, + Grantee: grantee, + Allowance: any, + }, + { + Granter: granter, + Grantee: grantee, + Allowance: any, + }, + }, + } + + // Validation should fail with duplicate feegrant error + err = ValidateGenesis(*genesisState) + assert.ErrorContains(t, err, "duplicate feegrant found") +}