package wasm_test
import (
"encoding/json"
"fmt"
"testing"
"github.com/CosmWasm/wasmd/x/wasm/keeper"
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
"github.com/stretchr/testify/require"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cybercongress/go-cyber/v7/app"
"github.com/cybercongress/go-cyber/v7/x/tokenfactory/types"
bindings "github.com/cybercongress/go-cyber/v7/x/tokenfactory/wasm/types"
)
func TestCreateDenomMsg(t *testing.T) {
creator := RandomAccountAddress()
junoapp, ctx := SetupCustomApp(t, creator)
lucky := RandomAccountAddress()
reflect := instantiateReflectContract(t, ctx, junoapp, lucky)
require.NotEmpty(t, reflect)
reflectAmount := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100)))
fundAccount(t, ctx, junoapp, reflect, reflectAmount)
msg := bindings.TokenFactoryMsg{CreateDenom: &bindings.CreateDenom{
Subdenom: "SUN",
}}
err := executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{})
require.NoError(t, err)
query := bindings.TokenFactoryQuery{
FullDenom: &bindings.FullDenom{
CreatorAddr: reflect.String(),
Subdenom: "SUN",
},
}
resp := bindings.FullDenomResponse{}
queryCustom(t, ctx, junoapp, reflect, query, &resp)
require.Equal(t, resp.Denom, fmt.Sprintf("factory/%s/SUN", reflect.String()))
}
func TestMintMsg(t *testing.T) {
creator := RandomAccountAddress()
junoapp, ctx := SetupCustomApp(t, creator)
lucky := RandomAccountAddress()
reflect := instantiateReflectContract(t, ctx, junoapp, lucky)
require.NotEmpty(t, reflect)
reflectAmount := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100)))
fundAccount(t, ctx, junoapp, reflect, reflectAmount)
balances := junoapp.AppKeepers.BankKeeper.GetAllBalances(ctx, lucky)
require.Empty(t, balances)
msg := bindings.TokenFactoryMsg{CreateDenom: &bindings.CreateDenom{
Subdenom: "SUN",
}}
err := executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{})
require.NoError(t, err)
sunDenom := fmt.Sprintf("factory/%s/%s", reflect.String(), msg.CreateDenom.Subdenom)
amount, ok := sdk.NewIntFromString("808010808")
require.True(t, ok)
msg = bindings.TokenFactoryMsg{MintTokens: &bindings.MintTokens{
Denom: sunDenom,
Amount: amount,
MintToAddress: lucky.String(),
}}
err = executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{})
require.NoError(t, err)
balances = junoapp.AppKeepers.BankKeeper.GetAllBalances(ctx, lucky)
require.Len(t, balances, 1)
coin := balances[0]
require.Equal(t, amount, coin.Amount)
require.Contains(t, coin.Denom, "factory/")
query := bindings.TokenFactoryQuery{
FullDenom: &bindings.FullDenom{
CreatorAddr: reflect.String(),
Subdenom: "SUN",
},
}
resp := bindings.FullDenomResponse{}
queryCustom(t, ctx, junoapp, reflect, query, &resp)
require.Equal(t, resp.Denom, coin.Denom)
err = executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{})
require.NoError(t, err)
balances = junoapp.AppKeepers.BankKeeper.GetAllBalances(ctx, lucky)
require.Len(t, balances, 1)
coin = balances[0]
require.Equal(t, amount.MulRaw(2), coin.Amount)
require.Contains(t, coin.Denom, "factory/")
query = bindings.TokenFactoryQuery{
FullDenom: &bindings.FullDenom{
CreatorAddr: reflect.String(),
Subdenom: "SUN",
},
}
resp = bindings.FullDenomResponse{}
queryCustom(t, ctx, junoapp, reflect, query, &resp)
require.Equal(t, resp.Denom, coin.Denom)
msg = bindings.TokenFactoryMsg{CreateDenom: &bindings.CreateDenom{
Subdenom: "MOON",
}}
err = executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{})
require.NoError(t, err)
moonDenom := fmt.Sprintf("factory/%s/%s", reflect.String(), msg.CreateDenom.Subdenom)
amount = amount.SubRaw(1)
msg = bindings.TokenFactoryMsg{MintTokens: &bindings.MintTokens{
Denom: moonDenom,
Amount: amount,
MintToAddress: lucky.String(),
}}
err = executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{})
require.NoError(t, err)
balances = junoapp.AppKeepers.BankKeeper.GetAllBalances(ctx, lucky)
require.Len(t, balances, 2)
coin = balances[0]
require.Equal(t, amount, coin.Amount)
require.Contains(t, coin.Denom, "factory/")
query = bindings.TokenFactoryQuery{
FullDenom: &bindings.FullDenom{
CreatorAddr: reflect.String(),
Subdenom: "MOON",
},
}
resp = bindings.FullDenomResponse{}
queryCustom(t, ctx, junoapp, reflect, query, &resp)
require.Equal(t, resp.Denom, coin.Denom)
coin = balances[1]
require.Equal(t, amount.AddRaw(1).MulRaw(2), coin.Amount)
require.Contains(t, coin.Denom, "factory/")
query = bindings.TokenFactoryQuery{
FullDenom: &bindings.FullDenom{
CreatorAddr: reflect.String(),
Subdenom: "SUN",
},
}
resp = bindings.FullDenomResponse{}
queryCustom(t, ctx, junoapp, reflect, query, &resp)
require.Equal(t, resp.Denom, coin.Denom)
}
func TestForceTransfer(t *testing.T) {
creator := RandomAccountAddress()
junoapp, ctx := SetupCustomApp(t, creator)
lucky := RandomAccountAddress()
rcpt := RandomAccountAddress()
reflect := instantiateReflectContract(t, ctx, junoapp, lucky)
require.NotEmpty(t, reflect)
reflectAmount := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100)))
fundAccount(t, ctx, junoapp, reflect, reflectAmount)
balances := junoapp.AppKeepers.BankKeeper.GetAllBalances(ctx, lucky)
require.Empty(t, balances)
msg := bindings.TokenFactoryMsg{CreateDenom: &bindings.CreateDenom{
Subdenom: "SUN",
}}
err := executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{})
require.NoError(t, err)
sunDenom := fmt.Sprintf("factory/%s/%s", reflect.String(), msg.CreateDenom.Subdenom)
amount, ok := sdk.NewIntFromString("808010808")
require.True(t, ok)
msg = bindings.TokenFactoryMsg{MintTokens: &bindings.MintTokens{
Denom: sunDenom,
Amount: amount,
MintToAddress: lucky.String(),
}}
err = executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{})
require.NoError(t, err)
msg = bindings.TokenFactoryMsg{ForceTransfer: &bindings.ForceTransfer{
Denom: sunDenom,
Amount: sdk.NewInt(100),
FromAddress: lucky.String(),
ToAddress: rcpt.String(),
}}
err = executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{})
require.NoError(t, err)
balances = junoapp.AppKeepers.BankKeeper.GetAllBalances(ctx, rcpt)
require.Len(t, balances, 1)
coin := balances[0]
require.Equal(t, sdk.NewInt(100), coin.Amount)
}
func TestBurnMsg(t *testing.T) {
creator := RandomAccountAddress()
junoapp, ctx := SetupCustomApp(t, creator)
lucky := RandomAccountAddress()
reflect := instantiateReflectContract(t, ctx, junoapp, lucky)
require.NotEmpty(t, reflect)
reflectAmount := sdk.NewCoins(sdk.NewCoin(types.DefaultParams().DenomCreationFee[0].Denom, types.DefaultParams().DenomCreationFee[0].Amount.MulRaw(100)))
fundAccount(t, ctx, junoapp, reflect, reflectAmount)
balances := junoapp.AppKeepers.BankKeeper.GetAllBalances(ctx, lucky)
require.Empty(t, balances)
msg := bindings.TokenFactoryMsg{CreateDenom: &bindings.CreateDenom{
Subdenom: "SUN",
}}
err := executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{})
require.NoError(t, err)
sunDenom := fmt.Sprintf("factory/%s/%s", reflect.String(), msg.CreateDenom.Subdenom)
amount, ok := sdk.NewIntFromString("808010809")
require.True(t, ok)
msg = bindings.TokenFactoryMsg{MintTokens: &bindings.MintTokens{
Denom: sunDenom,
Amount: amount,
MintToAddress: lucky.String(),
}}
err = executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{})
require.NoError(t, err)
amt, ok := sdk.NewIntFromString("1")
require.True(t, ok)
msg = bindings.TokenFactoryMsg{BurnTokens: &bindings.BurnTokens{
Denom: sunDenom,
Amount: amt,
BurnFromAddress: lucky.String(),
}}
err = executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{})
require.NoError(t, err)
luckyBalance := junoapp.AppKeepers.BankKeeper.GetAllBalances(ctx, lucky)
err = junoapp.AppKeepers.BankKeeper.SendCoins(ctx, lucky, reflect, luckyBalance)
require.NoError(t, err)
msg = bindings.TokenFactoryMsg{BurnTokens: &bindings.BurnTokens{
Denom: sunDenom,
Amount: amount.Abs().Sub(sdk.NewInt(1)),
BurnFromAddress: reflect.String(),
}}
err = executeCustom(t, ctx, junoapp, reflect, lucky, msg, sdk.Coin{})
require.NoError(t, err)
}
type ReflectExec struct {
ReflectMsg *ReflectMsgs `json:"reflect_msg,omitempty"`
ReflectSubMsg *ReflectSubMsgs `json:"reflect_sub_msg,omitempty"`
}
type ReflectMsgs struct {
Msgs []wasmvmtypes.CosmosMsg `json:"msgs"`
}
type ReflectSubMsgs struct {
Msgs []wasmvmtypes.SubMsg `json:"msgs"`
}
func executeCustom(t *testing.T, ctx sdk.Context, junoapp *app.App, contract sdk.AccAddress, sender sdk.AccAddress, msg bindings.TokenFactoryMsg, funds sdk.Coin) error { customBz, err := json.Marshal(msg)
require.NoError(t, err)
reflectMsg := ReflectExec{
ReflectMsg: &ReflectMsgs{
Msgs: []wasmvmtypes.CosmosMsg{{
Custom: customBz,
}},
},
}
reflectBz, err := json.Marshal(reflectMsg)
require.NoError(t, err)
var coins sdk.Coins
if !funds.Amount.IsNil() {
coins = sdk.Coins{funds}
}
contractKeeper := keeper.NewDefaultPermissionKeeper(junoapp.AppKeepers.WasmKeeper)
_, err = contractKeeper.Execute(ctx, contract, sender, reflectBz, coins)
return err
}