Skip to content

Commit

Permalink
[TokenFactory] Bank Hooks Integration (#4590)
Browse files Browse the repository at this point in the history
* Update sdk dependency

* Add integration for bank hooks

* Fix comments in go mod
  • Loading branch information
mattverse authored Mar 16, 2023
1 parent f70a0cc commit a1fa002
Show file tree
Hide file tree
Showing 18 changed files with 129 additions and 55 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,8 @@ replace (
github.com/CosmWasm/wasmd => github.com/osmosis-labs/wasmd v0.30.0-osmo-v15
// dragonberry
github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0
// Our cosmos-sdk branch is: https://github.com/osmosis-labs/cosmos-sdk, current branch: v15.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/44b40d47f3108c29f07fd115e5a92b387fb7a6bd
github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230228211301-44b40d47f310
// Our cosmos-sdk branch is: https://github.com/osmosis-labs/cosmos-sdk, current branch: v16.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/4f857c6a941a3e3849aad40aae1781e80f8e1dda
github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230313061712-4f857c6a941a
// use cosmos-compatible protobufs
github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
// Informal Tendermint fork
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -932,8 +932,8 @@ github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh
github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA=
github.com/ory/dockertest/v3 v3.9.1 h1:v4dkG+dlu76goxMiTT2j8zV7s4oPPEppKT8K8p2f1kY=
github.com/ory/dockertest/v3 v3.9.1/go.mod h1:42Ir9hmvaAPm0Mgibk6mBPi7SFvTXxEcnztDYOJ//uM=
github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230228211301-44b40d47f310 h1:3CTaTTiiFg/JoNLP2jGMjooQaeXSzQus/rZMllAlFy4=
github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230228211301-44b40d47f310/go.mod h1:rud0OaBIuq3+qOqtwT4SR7Q7iSzRp7w41fjninTjfnQ=
github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230313061712-4f857c6a941a h1:ycdLQR3ZhY0wmPEzgh4iLQB7GWsxTK+Y0/DClc7zStA=
github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230313061712-4f857c6a941a/go.mod h1:rud0OaBIuq3+qOqtwT4SR7Q7iSzRp7w41fjninTjfnQ=
github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3 h1:YlmchqTmlwdWSmrRmXKR+PcU96ntOd8u10vTaTZdcNY=
github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3/go.mod h1:lV6KnqXYD/ayTe7310MHtM3I2q8Z6bBfMAi+bhwPYtI=
github.com/osmosis-labs/osmosis/osmomath v0.0.0-20230105183030-bccf5202f260 h1:+EbINXzHQyDtHje2CND357A22H2zUpceTtwJClC9IAM=
Expand Down
4 changes: 2 additions & 2 deletions osmomath/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ require (
)

replace (
// Our cosmos-sdk branch is: https://github.com/osmosis-labs/cosmos-sdk, current branch: v15.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/44b40d47f3108c29f07fd115e5a92b387fb7a6bd
github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230228211301-44b40d47f310
// Our cosmos-sdk branch is: https://github.com/osmosis-labs/cosmos-sdk, current branch: v16.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/4f857c6a941a3e3849aad40aae1781e80f8e1dda
github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230313061712-4f857c6a941a
// use cosmos-compatible protobufs
github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
// use grpc compatible with cosmos protobufs
Expand Down
4 changes: 2 additions & 2 deletions osmoutils/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ require (
)

replace (
// Our cosmos-sdk branch is: https://github.com/osmosis-labs/cosmos-sdk, current branch: v15.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/44b40d47f3108c29f07fd115e5a92b387fb7a6bd
github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230228211301-44b40d47f310
// Our cosmos-sdk branch is: https://github.com/osmosis-labs/cosmos-sdk, current branch: v16.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/4f857c6a941a3e3849aad40aae1781e80f8e1dda
github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230313061712-4f857c6a941a
// use cosmos-compatible protobufs
github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
// use grpc compatible with cosmos protobufs
Expand Down
4 changes: 2 additions & 2 deletions tests/cl-go-client/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ replace (
github.com/CosmWasm/wasmd => github.com/osmosis-labs/wasmd v0.30.0-osmo-v15
// dragonberry
github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0
// Our cosmos-sdk branch is: https://github.com/osmosis-labs/cosmos-sdk, current branch: v15.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/44b40d47f3108c29f07fd115e5a92b387fb7a6bd
github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230228211301-44b40d47f310
// Our cosmos-sdk branch is: https://github.com/osmosis-labs/cosmos-sdk, current branch: v16.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/4f857c6a941a3e3849aad40aae1781e80f8e1dda
github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230313061712-4f857c6a941a
// use cosmos-compatible protobufs
github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1

Expand Down
3 changes: 0 additions & 3 deletions wasmbinding/message_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,6 @@ func PerformBurn(f *tokenfactorykeeper.Keeper, ctx sdk.Context, contractAddr sdk
if burn == nil {
return wasmvmtypes.InvalidRequest{Err: "burn token null mint"}
}
if burn.BurnFromAddress != "" && burn.BurnFromAddress != contractAddr.String() {
return wasmvmtypes.InvalidRequest{Err: "BurnFromAddress must be \"\""}
}

coin := sdk.Coin{Denom: burn.Denom, Amount: burn.Amount}
sdkMsg := tokenfactorytypes.NewMsgBurn(contractAddr.String(), coin)
Expand Down
2 changes: 1 addition & 1 deletion wasmbinding/test/messages_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ func TestBurn(t *testing.T) {
Amount: mintAmount,
BurnFromAddress: lucky.String(),
},
expErr: true,
expErr: false,
},
"empty sub-denom": {
burn: &bindings.BurnTokens{
Expand Down
4 changes: 2 additions & 2 deletions x/gamm/keeper/gas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ func (suite *KeeperTestSuite) TestJoinPoolGas() {

avgGas, maxGas := suite.measureAvgAndMaxJoinPoolGas(totalNumJoins, defaultAddr, poolIDFn, minShareOutAmountFn, maxCoinsFn)
fmt.Printf("test deets: total %d of pools joined, begin average at %d\n", totalNumJoins, startAveragingAt)
suite.Assert().LessOrEqual(int(avgGas), 100000, "average gas / join pool")
suite.Assert().LessOrEqual(int(maxGas), 100000, "max gas / join pool")
suite.Assert().LessOrEqual(int(avgGas), 101000, "average gas / join pool")
suite.Assert().LessOrEqual(int(maxGas), 101000, "max gas / join pool")
}

func (suite *KeeperTestSuite) TestRepeatedJoinPoolDistinctDenom() {
Expand Down
4 changes: 2 additions & 2 deletions x/ibc-hooks/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ replace (
github.com/CosmWasm/wasmd => github.com/osmosis-labs/wasmd v0.30.0-osmo-v15
// dragonberry
github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0
// Our cosmos-sdk branch is: https://github.com/osmosis-labs/cosmos-sdk, current branch: v15.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/44b40d47f3108c29f07fd115e5a92b387fb7a6bd
github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230228211301-44b40d47f310
// Our cosmos-sdk branch is: https://github.com/osmosis-labs/cosmos-sdk, current branch: v16.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/4f857c6a941a3e3849aad40aae1781e80f8e1dda
github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230313061712-4f857c6a941a
// use cosmos-compatible protobufs
github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
)
12 changes: 12 additions & 0 deletions x/tokenfactory/keeper/admins_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ func (suite *KeeperTestSuite) TestBurnDenom() {
balances[acc.String()] = 1000
}

// save sample module account address for testing
moduleAdress := suite.App.AccountKeeper.GetModuleAddress("developer_vesting_unvested")

for _, tc := range []struct {
desc string
burnMsg types.MsgBurn
Expand Down Expand Up @@ -205,6 +208,15 @@ func (suite *KeeperTestSuite) TestBurnDenom() {
),
expectPass: true,
},
{
desc: "fail case - burn from module account",
burnMsg: *types.NewMsgBurnFrom(
suite.TestAccs[0].String(),
sdk.NewInt64Coin(suite.defaultDenom, 10),
moduleAdress.String(),
),
expectPass: false,
},
} {
suite.Run(fmt.Sprintf("Case %s", tc.desc), func() {
_, err := suite.msgServer.Burn(sdk.WrapSDKContext(suite.Ctx), &tc.burnMsg)
Expand Down
54 changes: 37 additions & 17 deletions x/tokenfactory/keeper/before_send.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package keeper

import (
"encoding/json"
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"

"github.com/osmosis-labs/osmosis/v15/x/tokenfactory/types"

Expand Down Expand Up @@ -76,38 +76,58 @@ func (k Keeper) Hooks(wasmkeeper wasmKeeper.Keeper) Hooks {
return Hooks{k, wasmkeeper}
}

// implements BeforeSend hook in the Bank module.
// Calls the stored before send hook for the denom specificed.
func (h Hooks) BeforeSend(ctx sdk.Context, from, to sdk.AccAddress, amount sdk.Coins) error {
cwCoins := CWCoinsFromSDKCoins(amount)
// TrackBeforeSend calls the before send listener contract surpresses any errors
func (h Hooks) TrackBeforeSend(ctx sdk.Context, from, to sdk.AccAddress, amount sdk.Coins) {
_ = h.k.callBeforeSendListener(ctx, h.wasmkeeper, from, to, amount, false)
}

// TrackBeforeSend calls the before send listener contract returns any errors
func (h Hooks) BlockBeforeSend(ctx sdk.Context, from, to sdk.AccAddress, amount sdk.Coins) error {
return h.k.callBeforeSendListener(ctx, h.wasmkeeper, from, to, amount, true)
}

// callBeforeSendListener iterates over each coin and sends corresponding sudo msg to the contract address stored in state.
// If blockBeforeSend is true, sudoMsg wraps BlockBeforeSendMsg, otherwise sudoMsg wraps TrackBeforeSendMsg.
func (k Keeper) callBeforeSendListener(ctx sdk.Context, wasmKeeper wasmKeeper.Keeper, from, to sdk.AccAddress, amount sdk.Coins, blockBeforeSend bool) error {
for _, coin := range amount {
cosmwasmAddress := h.k.GetBeforeSendHook(ctx, coin.Denom)
cosmwasmAddress := k.GetBeforeSendHook(ctx, coin.Denom)
if cosmwasmAddress != "" {
cwAddr, err := sdk.AccAddressFromBech32(cosmwasmAddress)
if err != nil {
return err
}

msg := types.SudoMsg{
BeforeSend: types.BeforeSendMsg{
From: from.String(),
To: to.String(),
Amount: cwCoins,
},
var msgBz []byte

// get msgBz, either BlockBeforeSend or TrackBeforeSend
if blockBeforeSend {
msg := types.BlockBeforeSendSudoMsg{
BlockBeforeSend: types.BlockBeforeSendMsg{
From: from.String(),
To: to.String(),
Amount: CWCoinFromSDKCoin(coin),
},
}
msgBz, err = json.Marshal(msg)
} else {
msg := types.TrackBeforeSendSudoMsg{
TrackBeforeSend: types.TrackBeforeSendMsg{
From: from.String(),
To: to.String(),
Amount: CWCoinFromSDKCoin(coin),
},
}
msgBz, err = json.Marshal(msg)
}

msgBz, err := json.Marshal(msg)
if err != nil {
return err
}

em := sdk.NewEventManager()

_, err = h.wasmkeeper.Sudo(ctx.WithEventManager(em), cwAddr, msgBz)
fmt.Println(err)
_, err = wasmKeeper.Sudo(ctx.WithEventManager(em), cwAddr, msgBz)
if err != nil {
return err
return sdkerrors.Wrapf(err, "failed to call before send hook for denom %s", coin.Denom)
}
}
}
Expand Down
33 changes: 29 additions & 4 deletions x/tokenfactory/keeper/before_send_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,18 @@ func (suite *KeeperTestSuite) TestBeforeSendHook() {
wasmFile: "./testdata/no100.wasm",
sendMsgs: []SendMsgTestCase{
{
desc: "sending 100 of factorydenom should not work",
desc: "sending 1 of factorydenom should not error",
msg: func(factorydenom string) *banktypes.MsgSend {
return banktypes.NewMsgSend(
suite.TestAccs[0],
suite.TestAccs[1],
sdk.NewCoins(sdk.NewInt64Coin(factorydenom, 1)),
)
},
expectPass: true,
},
{
desc: "sending 100 of non-factorydenom should not error",
msg: func(factorydenom string) *banktypes.MsgSend {
return banktypes.NewMsgSend(
suite.TestAccs[0],
Expand All @@ -50,12 +61,23 @@ func (suite *KeeperTestSuite) TestBeforeSendHook() {
expectPass: false,
},
{
desc: "sending 100 of a non-factorydenom should not work",
desc: "sending 100 of factorydenom should not work",
msg: func(factorydenom string) *banktypes.MsgSend {
return banktypes.NewMsgSend(
suite.TestAccs[0],
suite.TestAccs[1],
sdk.NewCoins(sdk.NewInt64Coin("foo", 100)),
)
},
expectPass: false,
},
{
desc: "having 100 coin within coins should not work",
msg: func(factorydenom string) *banktypes.MsgSend {
return banktypes.NewMsgSend(
suite.TestAccs[0],
suite.TestAccs[1],
sdk.NewCoins(sdk.NewInt64Coin(factorydenom, 1), sdk.NewInt64Coin("uosmo", 100)),
sdk.NewCoins(sdk.NewInt64Coin(factorydenom, 100), sdk.NewInt64Coin("foo", 1)),
)
},
expectPass: false,
Expand All @@ -81,7 +103,10 @@ func (suite *KeeperTestSuite) TestBeforeSendHook() {
denom := res.GetNewTokenDenom()

// mint enough coins to the creator
suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(suite.TestAccs[0].String(), sdk.NewInt64Coin(denom, 1000000000)))
_, err = suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(suite.TestAccs[0].String(), sdk.NewInt64Coin(denom, 1000000000)))
suite.Require().NoError(err)
// mint some non token factory denom coins for testing
suite.FundAcc(sdk.AccAddress(suite.TestAccs[0].String()), sdk.Coins{sdk.NewInt64Coin("foo", 100000000000)})

// set beforesend hook to the new denom
_, err = suite.msgServer.SetBeforeSendHook(sdk.WrapSDKContext(suite.Ctx), types.NewMsgSetBeforeSendHook(suite.TestAccs[0].String(), denom, cosmwasmAddress.String()))
Expand Down
7 changes: 7 additions & 0 deletions x/tokenfactory/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"

sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"

"github.com/osmosis-labs/osmosis/v15/x/tokenfactory/types"
)
Expand Down Expand Up @@ -95,6 +96,12 @@ func (server msgServer) Burn(goCtx context.Context, msg *types.MsgBurn) (*types.
msg.BurnFromAddress = msg.Sender
}

accountI := server.Keeper.accountKeeper.GetAccount(ctx, sdk.AccAddress(msg.BurnFromAddress))
_, ok := accountI.(authtypes.ModuleAccountI)
if ok {
return nil, types.ErrBurnFromModuleAccount
}

err = server.Keeper.burnFrom(ctx, msg.Amount, msg.BurnFromAddress)
if err != nil {
return nil, err
Expand Down
Binary file modified x/tokenfactory/keeper/testdata/no100.wasm
Binary file not shown.
15 changes: 0 additions & 15 deletions x/tokenfactory/types/beforeSend.go

This file was deleted.

25 changes: 25 additions & 0 deletions x/tokenfactory/types/before_send.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package types

import (
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
)

type BlockBeforeSendSudoMsg struct {
BlockBeforeSend BlockBeforeSendMsg `json:"block_before_send,omitempty"`
}

type TrackBeforeSendSudoMsg struct {
TrackBeforeSend TrackBeforeSendMsg `json:"track_before_send"`
}

type TrackBeforeSendMsg struct {
From string `json:"from"`
To string `json:"to"`
Amount wasmvmtypes.Coin `json:"amount"`
}

type BlockBeforeSendMsg struct {
From string `json:"from"`
To string `json:"to"`
Amount wasmvmtypes.Coin `json:"amount"`
}
1 change: 1 addition & 0 deletions x/tokenfactory/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ var (
ErrSubdenomTooLong = sdkerrors.Register(ModuleName, 8, fmt.Sprintf("subdenom too long, max length is %d bytes", MaxSubdenomLength))
ErrCreatorTooLong = sdkerrors.Register(ModuleName, 9, fmt.Sprintf("creator too long, max length is %d bytes", MaxCreatorLength))
ErrDenomDoesNotExist = sdkerrors.Register(ModuleName, 10, "denom does not exist")
ErrBurnFromModuleAccount = sdkerrors.Register(ModuleName, 11, "burning from Module Account is not allowed")
)
4 changes: 3 additions & 1 deletion x/tokenfactory/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ type BankKeeper interface {
}

type AccountKeeper interface {
GetAccount(sdk.Context, sdk.AccAddress) authtypes.AccountI
SetModuleAccount(ctx sdk.Context, macc authtypes.ModuleAccountI)
}

// BankHooks event hooks
type BankHooks interface {
BeforeSend(ctx sdk.Context, from, to sdk.AccAddress, amount sdk.Coins) error // Must be called when a bank transfer happens
TrackBeforeSend(ctx sdk.Context, from, to sdk.AccAddress, amount sdk.Coins) // Must be before any send is executed
BlockBeforeSend(ctx sdk.Context, from, to sdk.AccAddress, amount sdk.Coins) error // Must be before any send is executed
}

// CommunityPoolKeeper defines the contract needed to be fulfilled for community pool interactions.
Expand Down

0 comments on commit a1fa002

Please sign in to comment.