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

feat: whitelist addresses param for setting fee tokens #7855

Merged
merged 10 commits into from
Apr 1, 2024
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* [#7785](https://github.com/osmosis-labs/osmosis/pull/7785) Remove reward claiming during position transfers
* [#7839](https://github.com/osmosis-labs/osmosis/pull/7839) Add ICA controller
* [#7527](https://github.com/osmosis-labs/osmosis/pull/7527) Add 30M gas limit to CW pool contract calls
* [#7855](https://github.com/osmosis-labs/osmosis/pull/7855) Whitelist address parameter for setting fee tokens

### SDK

Expand All @@ -87,6 +88,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* [#514](https://github.com/osmosis-labs/cosmos-sdk/pull/514) Let gov hooks return an error
* [#580](https://github.com/osmosis-labs/cosmos-sdk/pull/580) Less time intensive slashing migration

### CometBFT

* [#5](https://github.com/osmosis-labs/cometbft/pull/5) Batch verification
* [#11](https://github.com/osmosis-labs/cometbft/pull/11) Skip verification of commit sigs
* [#13](https://github.com/osmosis-labs/cometbft/pull/13) Avoid double-saving ABCI responses
* [#20](https://github.com/osmosis-labs/cometbft/pull/20) Fix the rollback command

Comment on lines +94 to +100
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drive by change

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the update in a separate PR.

#7865

## v23.0.8-iavl-v1 & v23.0.8

* [#7769](https://github.com/osmosis-labs/osmosis/pull/7769) Set and default timeout commit to 3s. Add flag to prevent custom overrides if not desired.
Expand Down
3 changes: 3 additions & 0 deletions app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
icacontroller "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller"
icacontrollerkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/keeper"
icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types"

appparams "github.com/osmosis-labs/osmosis/v23/app/params"
"github.com/osmosis-labs/osmosis/v23/x/cosmwasmpool"
cosmwasmpooltypes "github.com/osmosis-labs/osmosis/v23/x/cosmwasmpool/types"
Expand Down Expand Up @@ -442,6 +443,7 @@ func (appKeepers *AppKeepers) InitNormalKeepers(
appKeepers.DistrKeeper,
appKeepers.ConsensusParamsKeeper,
dataDir,
appKeepers.GetSubspace(txfeestypes.ModuleName),
)
appKeepers.TxFeesKeeper = &txFeesKeeper

Expand Down Expand Up @@ -752,6 +754,7 @@ func (appKeepers *AppKeepers) initParamsKeeper(appCodec codec.BinaryCodec, legac
paramsKeeper.Subspace(packetforwardtypes.ModuleName).WithKeyTable(packetforwardtypes.ParamKeyTable())
paramsKeeper.Subspace(cosmwasmpooltypes.ModuleName)
paramsKeeper.Subspace(ibchookstypes.ModuleName)
paramsKeeper.Subspace(txfeestypes.ModuleName)

return paramsKeeper
}
Expand Down
7 changes: 7 additions & 0 deletions app/upgrades/v24/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/cosmos/cosmos-sdk/types/module"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types"

cwpooltypes "github.com/osmosis-labs/osmosis/v23/x/cosmwasmpool/types"

"github.com/osmosis-labs/osmosis/v23/app/keepers"
Expand Down Expand Up @@ -80,6 +81,12 @@ func CreateUpgradeHandler(
keepers.CosmwasmPoolKeeper.SetPool(ctx, cwPool)
}

// TODO: Uncomment, set, and add to upgrade_test.go IFF an address is decided on via the governance forums prior to upgrade.
// Otherwise, this will be set after v24 via a parameter change proposal.

// Set whitelistedFeeTokenSetters param
// keepers.TxFeesKeeper.SetParam(ctx, txfeestypes.KeyWhitelistedFeeTokenSetters, "osmo1...")

czarcas7ic marked this conversation as resolved.
Show resolved Hide resolved
return migrations, nil
}
}
4 changes: 4 additions & 0 deletions proto/osmosis/txfees/v1beta1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package osmosis.txfees.v1beta1;
import "gogoproto/gogo.proto";
import "osmosis/txfees/v1beta1/feetoken.proto";
import "cosmos/base/v1beta1/coin.proto";
import "osmosis/txfees/v1beta1/params.proto";

option go_package = "github.com/osmosis-labs/osmosis/v23/x/txfees/types";

Expand All @@ -16,4 +17,7 @@ message GenesisState {
// TxFeesTracker txFeesTracker = 3;
reserved 3;
reserved "txFeesTracker";

// params is the container of txfees parameters.
Params params = 4 [ (gogoproto.nullable) = false ];
}
14 changes: 14 additions & 0 deletions proto/osmosis/txfees/v1beta1/params.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
syntax = "proto3";
package osmosis.txfees.v1beta1;

import "gogoproto/gogo.proto";

option go_package = "github.com/osmosis-labs/osmosis/v23/x/txfees/types";

// Params holds parameters for the txfees module
message Params {
repeated string whitelisted_fee_token_setters = 1 [
(gogoproto.moretags) = "yaml:\"whitelisted_fee_token_setters\"",
(gogoproto.nullable) = false
];
}
25 changes: 25 additions & 0 deletions proto/osmosis/txfees/v1beta1/tx.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
syntax = "proto3";
package osmosis.txfees.v1beta1;

import "gogoproto/gogo.proto";
import "amino/amino.proto";
import "osmosis/txfees/v1beta1/feetoken.proto";

option go_package = "github.com/osmosis-labs/osmosis/v23/x/txfees/types";

service Msg {
rpc SetFeeTokens(MsgSetFeeTokens) returns (MsgSetFeeTokensResponse);
}

// ===================== MsgSetFeeTokens
message MsgSetFeeTokens {
option (amino.name) = "osmosis/set-fee-tokens";

repeated FeeToken fee_tokens = 1 [
(gogoproto.moretags) = "yaml:\"fee_tokens\"",
(gogoproto.nullable) = false
];
string sender = 2 [ (gogoproto.moretags) = "yaml:\"sender\"" ];
}

message MsgSetFeeTokensResponse {}
3 changes: 3 additions & 0 deletions x/txfees/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"github.com/spf13/cobra"

"github.com/osmosis-labs/osmosis/osmoutils/osmocli"
"github.com/osmosis-labs/osmosis/v23/x/twap/client/queryproto"
"github.com/osmosis-labs/osmosis/v23/x/txfees/types"
)

Expand All @@ -15,6 +16,8 @@ func GetQueryCmd() *cobra.Command {
GetCmdFeeTokens(),
GetCmdDenomPoolID(),
GetCmdBaseDenom(),
osmocli.GetParams[*queryproto.ParamsRequest](
types.ModuleName, queryproto.NewQueryClient),
)

osmocli.AddQueryCmd(cmd, types.NewQueryClient, GetCmdQueryBaseFee)
Expand Down
19 changes: 19 additions & 0 deletions x/txfees/keeper/feetokens.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,22 @@ func (k Keeper) SetFeeTokens(ctx sdk.Context, feetokens []types.FeeToken) error
}
return nil
}

// SenderValidationSetFeeTokens first checks to see if the sender is whitelisted to set fee tokens.
// If the sender is whitelisted, it sets the fee tokens.
// If the sender is not whitelisted, it returns an error.
func (k Keeper) SenderValidationSetFeeTokens(ctx sdk.Context, sender string, feetokens []types.FeeToken) error {
whitelistedAddresses := k.GetParams(ctx).WhitelistedFeeTokenSetters
isWhitelisted := false
for _, admin := range whitelistedAddresses {
if admin == sender {
isWhitelisted = true
break
}
}
czarcas7ic marked this conversation as resolved.
Show resolved Hide resolved
if !isWhitelisted {
return errorsmod.Wrapf(types.ErrNotWhitelistedFeeTokenSetter, "%s", sender)
}

return k.SetFeeTokens(ctx, feetokens)
}
97 changes: 97 additions & 0 deletions x/txfees/keeper/feetokens_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package keeper_test

import (
"fmt"

"github.com/osmosis-labs/osmosis/osmomath"
"github.com/osmosis-labs/osmosis/v23/x/txfees/types"

Expand Down Expand Up @@ -281,3 +283,98 @@ func (s *KeeperTestSuite) TestFeeTokenConversions() {
})
}
}

func (s *KeeperTestSuite) TestSenderValidationSetFeeTokens() {
s.SetupTest(false)

baseDenom, _ := s.App.TxFeesKeeper.GetBaseDenom(s.Ctx)

tests := []struct {
name string
isWhitelistedAddr bool
prepareFeePools bool
feeTokensToSet []types.FeeToken
expectedError error
}{
{
name: "Set multiple fee tokens with whitelisted address",
feeTokensToSet: []types.FeeToken{
{Denom: "foo", PoolID: 1},
{Denom: "bar", PoolID: 2},
},
prepareFeePools: true,
isWhitelistedAddr: true,
},
{
name: "Set single fee token with whitelisted address",
feeTokensToSet: []types.FeeToken{
{Denom: "foo", PoolID: 1},
},
prepareFeePools: true,
isWhitelistedAddr: true,
},
{
name: "Error: Set multiple fee tokens with non-whitelisted address",
feeTokensToSet: []types.FeeToken{
{Denom: "foo", PoolID: 1},
{Denom: "bar", PoolID: 2},
},
prepareFeePools: true,
isWhitelistedAddr: false,
expectedError: types.ErrNotWhitelistedFeeTokenSetter,
},
{
name: "Error: Set single fee token with non-whitelisted address",
feeTokensToSet: []types.FeeToken{
{Denom: "foo", PoolID: 1},
},
prepareFeePools: true,
isWhitelistedAddr: false,
expectedError: types.ErrNotWhitelistedFeeTokenSetter,
},
{
name: "Error: Set single fee token with whitelisted address with fee pool not set",
feeTokensToSet: []types.FeeToken{
{Denom: "foo", PoolID: 1},
},
prepareFeePools: false,
isWhitelistedAddr: true,
expectedError: fmt.Errorf("failed to find route for pool id (1)"),
},
}

for _, tc := range tests {
s.SetupTest(false)

s.Run(tc.name, func() {
if tc.prepareFeePools {
for _, feeToken := range tc.feeTokensToSet {
s.PrepareBalancerPoolWithCoins(sdk.NewInt64Coin(baseDenom, 100), sdk.NewInt64Coin(feeToken.Denom, 100))
}
}

if tc.isWhitelistedAddr {
s.App.TxFeesKeeper.SetParam(s.Ctx, types.KeyWhitelistedFeeTokenSetters, []string{s.TestAccs[0].String()})
}

// Retrieve fee tokens before setting
feeTokensBefore := s.App.TxFeesKeeper.GetFeeTokens(s.Ctx)

err := s.App.TxFeesKeeper.SenderValidationSetFeeTokens(s.Ctx, s.TestAccs[0].String(), tc.feeTokensToSet)

// Retrieve fee tokens after setting
feeTokensAfter := s.App.TxFeesKeeper.GetFeeTokens(s.Ctx)

if tc.expectedError != nil {
s.Require().Error(err)
s.Require().ErrorContains(err, tc.expectedError.Error())
// Ensure that the fee tokens are the same
s.Require().Equal(len(feeTokensAfter), len(feeTokensBefore))
} else {
s.Require().NoError(err)
// Ensure that the fee tokens now include the new fee tokens
s.Require().Equal(len(feeTokensAfter), len(feeTokensBefore)+len(tc.feeTokensToSet))
}
})
}
}
2 changes: 2 additions & 0 deletions x/txfees/keeper/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ func (k Keeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) {
if err != nil {
panic(err)
}
k.SetParams(ctx, genState.Params)
}

// ExportGenesis returns the txfees module's exported genesis.
func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState {
genesis := types.DefaultGenesis()
genesis.Basedenom, _ = k.GetBaseDenom(ctx)
genesis.Feetokens = k.GetFeeTokens(ctx)
genesis.Params = k.GetParams(ctx)
return genesis
}
12 changes: 11 additions & 1 deletion x/txfees/keeper/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ var (
PoolID: 2,
},
}
testWhitelistAddrs = []string{"osmo106x8q2nv7xsg7qrec2zgdf3vvq0t3gn49zvaha", "osmo105l5r3rjtynn7lg362r2m9hkpfvmgmjtkglsn9"}
)

func (s *KeeperTestSuite) TestInitGenesis() {
Expand All @@ -28,13 +29,18 @@ func (s *KeeperTestSuite) TestInitGenesis() {
s.App.TxFeesKeeper.InitGenesis(s.Ctx, types.GenesisState{
Basedenom: testBaseDenom,
Feetokens: testFeeTokens,
Params: types.Params{
WhitelistedFeeTokenSetters: testWhitelistAddrs,
},
})

actualBaseDenom, err := s.App.TxFeesKeeper.GetBaseDenom(s.Ctx)
s.Require().NoError(err)

s.Require().Equal(testBaseDenom, actualBaseDenom)
s.Require().Equal(testFeeTokens, s.App.TxFeesKeeper.GetFeeTokens(s.Ctx))

actualParams := s.App.TxFeesKeeper.GetParams(s.Ctx)
s.Require().Equal(testWhitelistAddrs, actualParams.WhitelistedFeeTokenSetters)
}

func (s *KeeperTestSuite) TestExportGenesis() {
Expand All @@ -45,9 +51,13 @@ func (s *KeeperTestSuite) TestExportGenesis() {
s.App.TxFeesKeeper.InitGenesis(s.Ctx, types.GenesisState{
Basedenom: testBaseDenom,
Feetokens: testFeeTokens,
Params: types.Params{
WhitelistedFeeTokenSetters: testWhitelistAddrs,
},
})

genesis := s.App.TxFeesKeeper.ExportGenesis(s.Ctx)
s.Require().Equal(testBaseDenom, genesis.Basedenom)
s.Require().Equal(testFeeTokens, genesis.Feetokens)
s.Require().Equal(testWhitelistAddrs, genesis.Params.WhitelistedFeeTokenSetters)
}
26 changes: 26 additions & 0 deletions x/txfees/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/osmosis-labs/osmosis/v23/x/txfees/types"

storetypes "github.com/cosmos/cosmos-sdk/store/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"

tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
)
Expand All @@ -25,6 +26,8 @@ type Keeper struct {
distributionKeeper types.DistributionKeeper
consensusKeeper types.ConsensusKeeper
dataDir string

paramSpace paramtypes.Subspace
}

var _ types.TxFeesKeeper = (*Keeper)(nil)
Expand All @@ -38,7 +41,13 @@ func NewKeeper(
distributionKeeper types.DistributionKeeper,
consensusKeeper types.ConsensusKeeper,
dataDir string,
paramSpace paramtypes.Subspace,
) Keeper {
// set KeyTable if it has not already been set
if !paramSpace.HasKeyTable() {
paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable())
}

return Keeper{
accountKeeper: accountKeeper,
bankKeeper: bankKeeper,
Expand All @@ -48,9 +57,26 @@ func NewKeeper(
distributionKeeper: distributionKeeper,
consensusKeeper: consensusKeeper,
dataDir: dataDir,
paramSpace: paramSpace,
}
}

// GetParams returns the total set of txfees parameters.
func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) {
k.paramSpace.GetParamSet(ctx, &params)
return params
}

// SetParams sets the total set of txfees parameters.
func (k Keeper) SetParams(ctx sdk.Context, params types.Params) {
k.paramSpace.SetParamSet(ctx, &params)
}

// SetParam sets a specific txfees module's parameter with the provided parameter.
func (k Keeper) SetParam(ctx sdk.Context, key []byte, value interface{}) {
k.paramSpace.Set(ctx, key, value)
}

func (k Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName))
}
Expand Down
Loading