Skip to content

Commit

Permalink
feat: restrict token transfers to payment accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
yutianwu committed Aug 24, 2023
1 parent 259b456 commit 97f0d0e
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 10 deletions.
5 changes: 3 additions & 2 deletions simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ import (
dbm "github.com/cometbft/cometbft-db"
abci "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/libs/log"
"github.com/spf13/cast"

"github.com/cosmos/cosmos-sdk/x/crosschain"
"github.com/cosmos/cosmos-sdk/x/oracle"
"github.com/spf13/cast"

crosschainkeeper "github.com/cosmos/cosmos-sdk/x/crosschain/keeper"
crosschaintypes "github.com/cosmos/cosmos-sdk/x/crosschain/types"
Expand Down Expand Up @@ -415,7 +416,7 @@ func NewSimApp(
),
auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)),
vesting.NewAppModule(app.AccountKeeper, app.BankKeeper),
bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper, app.GetSubspace(banktypes.ModuleName)),
bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper, nil, app.GetSubspace(banktypes.ModuleName)),
capability.NewAppModule(appCodec, *app.CapabilityKeeper, false),
crisis.NewAppModule(app.CrisisKeeper, skipGenesisInvariants, app.GetSubspace(crisistypes.ModuleName)),
feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry),
Expand Down
4 changes: 2 additions & 2 deletions tests/integration/bank/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func newBarCoin(amt int64) sdk.Coin {
return sdk.NewInt64Coin(barDenom, amt)
}

//nolint: interfacer
// nolint: interfacer
func getCoinsByName(ctx sdk.Context, bk keeper.Keeper, ak types.AccountKeeper, moduleName string) sdk.Coins {
moduleAddress := ak.GetModuleAddress(moduleName)
macc := ak.GetAccount(ctx, moduleAddress)
Expand Down Expand Up @@ -150,7 +150,7 @@ func (suite *IntegrationTestSuite) SetupTest() {
types.RegisterInterfaces(interfaceRegistry)

suite.queryClient = queryClient
suite.msgServer = keeper.NewMsgServerImpl(suite.bankKeeper)
suite.msgServer = keeper.NewMsgServerImpl(suite.bankKeeper, nil)
}

func (suite *IntegrationTestSuite) TestSupply() {
Expand Down
2 changes: 1 addition & 1 deletion x/bank/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func (suite *KeeperTestSuite) SetupTest() {
queryClient := banktypes.NewQueryClient(queryHelper)

suite.queryClient = queryClient
suite.msgServer = keeper.NewMsgServerImpl(suite.bankKeeper)
suite.msgServer = keeper.NewMsgServerImpl(suite.bankKeeper, nil)
suite.encCfg = encCfg
}

Expand Down
18 changes: 16 additions & 2 deletions x/bank/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,20 @@ import (
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/bank/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)

type msgServer struct {
Keeper
PaymentKeeper types.PaymentKeeper
}

var _ types.MsgServer = msgServer{}

// NewMsgServerImpl returns an implementation of the bank MsgServer interface
// for the provided Keeper.
func NewMsgServerImpl(keeper Keeper) types.MsgServer {
return &msgServer{Keeper: keeper}
func NewMsgServerImpl(keeper Keeper, paymentKeeper types.PaymentKeeper) types.MsgServer {
return &msgServer{Keeper: keeper, PaymentKeeper: paymentKeeper}
}

func (k msgServer) Send(goCtx context.Context, msg *types.MsgSend) (*types.MsgSendResponse, error) {
Expand All @@ -44,6 +46,12 @@ func (k msgServer) Send(goCtx context.Context, msg *types.MsgSend) (*types.MsgSe
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive funds", msg.ToAddress)
}

if ctx.IsUpgraded(upgradetypes.Nagqu) {
if k.PaymentKeeper != nil && k.PaymentKeeper.IsPaymentAccount(ctx, to) {
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "payment account %s is not allowed to receive funds", msg.ToAddress)
}
}

err = k.SendCoins(ctx, from, to, msg.Amount)
if err != nil {
return nil, err
Expand Down Expand Up @@ -80,6 +88,12 @@ func (k msgServer) MultiSend(goCtx context.Context, msg *types.MsgMultiSend) (*t
if k.BlockedAddr(accAddr) {
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive funds", out.Address)
}

if ctx.IsUpgraded(upgradetypes.Nagqu) {
if k.PaymentKeeper != nil && k.PaymentKeeper.IsPaymentAccount(ctx, accAddr) {
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "payment account %s is not allowed to receive funds", accAddr)
}
}
}

err := k.InputOutputCoins(ctx, msg.Inputs, msg.Outputs)
Expand Down
8 changes: 5 additions & 3 deletions x/bank/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ type AppModule struct {

keeper keeper.Keeper
accountKeeper types.AccountKeeper
paymentKeeper types.PaymentKeeper

// legacySubspace is used solely for migration of x/params managed parameters
legacySubspace exported.Subspace
Expand All @@ -115,7 +116,7 @@ func (am AppModule) IsAppModule() {}

// RegisterServices registers module services.
func (am AppModule) RegisterServices(cfg module.Configurator) {
types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper))
types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper, am.paymentKeeper))
types.RegisterQueryServer(cfg.QueryServer(), am.keeper)

m := keeper.NewMigrator(am.keeper.(keeper.BaseKeeper), am.legacySubspace)
Expand All @@ -133,11 +134,12 @@ func (am AppModule) RegisterServices(cfg module.Configurator) {
}

// NewAppModule creates a new AppModule object
func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, accountKeeper types.AccountKeeper, ss exported.Subspace) AppModule {
func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, accountKeeper types.AccountKeeper, paymentKeeper types.PaymentKeeper, ss exported.Subspace) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{cdc: cdc},
keeper: keeper,
accountKeeper: accountKeeper,
paymentKeeper: paymentKeeper,
legacySubspace: ss,
}
}
Expand Down Expand Up @@ -254,7 +256,7 @@ func ProvideModule(in BankInputs) BankOutputs {
blockedAddresses,
authority.String(),
)
m := NewAppModule(in.Cdc, bankKeeper, in.AccountKeeper, in.LegacySubspace)
m := NewAppModule(in.Cdc, bankKeeper, in.AccountKeeper, nil, in.LegacySubspace)

return BankOutputs{BankKeeper: bankKeeper, Module: m}
}
37 changes: 37 additions & 0 deletions x/bank/testutil/expected_keepers_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions x/bank/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,10 @@ type AccountKeeper interface {
SetModuleAccount(ctx sdk.Context, macc types.ModuleAccountI)
GetModulePermissions() map[string]types.PermissionsForAddress
}

type PaymentKeeper interface {
IsPaymentAccount(
ctx sdk.Context,
addr sdk.AccAddress,
) bool
}

0 comments on commit 97f0d0e

Please sign in to comment.