diff --git a/app/app.go b/app/app.go index af04a7b11..0d105a861 100644 --- a/app/app.go +++ b/app/app.go @@ -284,7 +284,7 @@ var ( auctiontypes.ModuleName: nil, ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, icatypes.ModuleName: nil, - wasmtypes.ModuleName: {}, + wasmtypes.ModuleName: {authtypes.Burner}, interchainqueriesmoduletypes.ModuleName: nil, feetypes.ModuleName: nil, feeburnertypes.ModuleName: nil, diff --git a/wasmbinding/test/custom_message_test.go b/wasmbinding/test/custom_message_test.go index fe15d1d10..7ed2fc34a 100644 --- a/wasmbinding/test/custom_message_test.go +++ b/wasmbinding/test/custom_message_test.go @@ -3,8 +3,13 @@ package test import ( "encoding/json" "fmt" + "strings" "testing" + transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + ibctesting "github.com/cosmos/ibc-go/v8/testing" + contractmanagertypes "github.com/neutron-org/neutron/v4/x/contractmanager/types" types2 "github.com/neutron-org/neutron/v4/x/cron/types" @@ -79,7 +84,7 @@ func (suite *CustomMessengerTestSuite) SetupTest() { suite.contractKeeper = keeper.NewDefaultPermissionKeeper(&suite.neutron.WasmKeeper) err := suite.messenger.TokenFactory.SetParams(suite.ctx, tokenfactorytypes.NewParams( - sdk.NewCoins(sdk.NewInt64Coin(params.DefaultDenom, 10_000_000)), + sdk.NewCoins(sdk.NewInt64Coin(params.DefaultDenom, 100)), 0, FeeCollectorAddress, tokenfactorytypes.DefaultWhitelistedHooks, @@ -731,6 +736,100 @@ func (suite *CustomMessengerTestSuite) TestAddRemoveSchedule() { suite.NoError(err) } +func (suite *CustomMessengerTestSuite) TestBurnTokens() { + // add NTRN to the contract + senderAddress := suite.ChainA.SenderAccounts[0].SenderAccount.GetAddress() + coinsAmnt := sdk.NewCoins(sdk.NewCoin(params.DefaultDenom, math.NewInt(int64(10_000_000)))) + bankKeeper := suite.neutron.BankKeeper + err := bankKeeper.SendCoins(suite.ctx, senderAddress, suite.contractAddress, coinsAmnt) + suite.NoError(err) + + suite.ConfigureTransferChannel() + + // add IBC denom to the contract + // Create Transfer Msg + transferMsg := transfertypes.NewMsgTransfer(suite.TransferPath.EndpointB.ChannelConfig.PortID, + suite.TransferPath.EndpointB.ChannelID, + sdk.NewCoin(params.DefaultDenom, math.NewInt(100)), + suite.ChainB.SenderAccounts[0].SenderAccount.GetAddress().String(), + strings.TrimSpace(suite.contractAddress.String()), + clienttypes.NewHeight(1, 110), + 0, + "", + ) + + // Send message from chainB to chainA + res, err := suite.TransferPath.EndpointB.Chain.SendMsgs(transferMsg) + suite.Require().NoError(err) + + // Relay transfer msg to Neutron chain + packet, err := ibctesting.ParsePacketFromEvents(res.GetEvents()) + suite.Require().NoError(err) + + suite.Require().NoError(suite.TransferPath.RelayPacket(packet)) + // ----------------------------------- + + // Add tf token to the contract + // Create denom for minting + fullMsg := bindings.NeutronMsg{ + CreateDenom: &bindings.CreateDenom{ + Subdenom: "tfdenom", + }, + } + + _, err = suite.executeNeutronMsg(suite.contractAddress, fullMsg) + suite.NoError(err) + + tfDenom := fmt.Sprintf("factory/%s/%s", suite.contractAddress.String(), fullMsg.CreateDenom.Subdenom) + + amount, ok := math.NewIntFromString("808010808") + require.True(suite.T(), ok) + + fullMsg = bindings.NeutronMsg{ + MintTokens: &bindings.MintTokens{ + Denom: tfDenom, + Amount: amount, + MintToAddress: suite.contractAddress.String(), + }, + } + + _, err = suite.executeNeutronMsg(suite.contractAddress, fullMsg) + suite.NoError(err) + + type testCase struct { + Name string + CoinToBurn sdk.Coin + } + + ibcTokenDenomHash, err := suite.neutron.TransferKeeper.DenomHash( + suite.ctx, + &transfertypes.QueryDenomHashRequest{Trace: ibctesting.TransferPort + "/" + suite.TransferPath.EndpointA.ChannelID + "/" + params.DefaultDenom}) + suite.Require().NoError(err) + + testcases := []testCase{ + {Name: "burn NTRN", CoinToBurn: sdk.NewCoin(params.DefaultDenom, math.NewInt(1000))}, + {Name: "burn tf denom", CoinToBurn: sdk.NewCoin(tfDenom, math.NewInt(1000))}, + {Name: "burn ibc denom", CoinToBurn: sdk.NewCoin("ibc/"+ibcTokenDenomHash.Hash, math.NewInt(50))}, + } + + for _, tc := range testcases { + suite.Run(tc.Name, func() { + balanceBeforeBurn := bankKeeper.GetBalance(suite.ctx, suite.contractAddress, tc.CoinToBurn.Denom) + + // Craft Burn message + msg := types.CosmosMsg{ + Bank: &types.BankMsg{Burn: &types.BurnMsg{Amount: types.Array[types.Coin]{types.Coin{Amount: tc.CoinToBurn.Amount.String(), Denom: tc.CoinToBurn.Denom}}}}, + } + + // Dispatch Burn message + _, err = suite.executeMsg(suite.contractAddress, msg) + suite.NoError(err) + + suite.Require().Equal(balanceBeforeBurn.Sub(tc.CoinToBurn), bankKeeper.GetBalance(suite.ctx, suite.contractAddress, tc.CoinToBurn.Denom)) + }) + } +} + func (suite *CustomMessengerTestSuite) TestResubmitFailureAck() { // Add failure packet := ibcchanneltypes.Packet{} @@ -812,6 +911,10 @@ func (suite *CustomMessengerTestSuite) executeCustomMsg(contractAddress sdk.AccA Custom: fullMsg, } + return suite.executeMsg(contractAddress, customMsg) +} + +func (suite *CustomMessengerTestSuite) executeMsg(contractAddress sdk.AccAddress, fullMsg types.CosmosMsg) (data []byte, err error) { type ExecuteMsg struct { ReflectMsg struct { Msgs []types.CosmosMsg `json:"msgs"` @@ -820,7 +923,7 @@ func (suite *CustomMessengerTestSuite) executeCustomMsg(contractAddress sdk.AccA execMsg := ExecuteMsg{ReflectMsg: struct { Msgs []types.CosmosMsg `json:"msgs"` - }(struct{ Msgs []types.CosmosMsg }{Msgs: []types.CosmosMsg{customMsg}})} + }(struct{ Msgs []types.CosmosMsg }{Msgs: []types.CosmosMsg{fullMsg}})} msg, err := json.Marshal(execMsg) suite.NoError(err)