Skip to content

Commit

Permalink
fix(rollapp): allow tokenless on CreateRollapp / UpdateRollapp wi…
Browse files Browse the repository at this point in the history
…th eip (#1685)
  • Loading branch information
mtsitrin authored Dec 30, 2024
1 parent 94f7ccd commit 8bdde21
Show file tree
Hide file tree
Showing 6 changed files with 243 additions and 13 deletions.
214 changes: 214 additions & 0 deletions app/ante/eip712_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
package ante_test

import (
"encoding/json"
"strings"
"time"

"cosmossdk.io/math"
"github.com/cometbft/cometbft/libs/rand"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
authz "github.com/cosmos/cosmos-sdk/x/authz"
bankutil "github.com/cosmos/cosmos-sdk/x/bank/testutil"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
feegrant "github.com/cosmos/cosmos-sdk/x/feegrant"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"

"github.com/dymensionxyz/dymension/v3/app/params"
rollapptypes "github.com/dymensionxyz/dymension/v3/x/rollapp/types"
"github.com/ethereum/go-ethereum/signer/core/apitypes"
"github.com/evmos/ethermint/crypto/ethsecp256k1"
"github.com/evmos/ethermint/ethereum/eip712"
ethermint "github.com/evmos/ethermint/types"
)

func (s *AnteTestSuite) getMsgSend(from sdk.AccAddress) sdk.Msg {
privkey2, _ := ethsecp256k1.GenerateKey()
to := sdk.AccAddress(privkey2.PubKey().Address())
return banktypes.NewMsgSend(from, to, sdk.NewCoins(sdk.NewCoin(params.DisplayDenom, sdk.NewInt(1))))
}

/*
func createIRO() sdk.Msg {
return &irotypes.MsgCreatePlan{
Owner: "",
RollappId: "",
AllocatedAmount: sdk.Int{},
BondingCurve: irotypes.BondingCurve{},
StartTime: time.Time{},
IroPlanDuration: 0,
IncentivePlanParams: irotypes.IncentivePlanParams{},
}
}
*/

func (s *AnteTestSuite) getMsgGrant(msgTypeUrl string, from sdk.AccAddress) *authz.MsgGrant {
privkey2, _ := ethsecp256k1.GenerateKey()
to := sdk.AccAddress(privkey2.PubKey().Address())

expDate := time.Now().Add(1 * time.Hour)
msg, err := authz.NewMsgGrant(
from,
to,
authz.NewGenericAuthorization(msgTypeUrl),
&expDate,
)
if err != nil {
panic(err)
}
return msg
}

func (s *AnteTestSuite) getMsgSubmitProposal(from sdk.AccAddress) sdk.Msg {
proposal, ok := govtypes.ContentFromProposalType("My proposal", "My description", govtypes.ProposalTypeText)
s.Require().True(ok)
deposit := sdk.NewCoins(sdk.NewCoin(params.DisplayDenom, sdk.NewInt(10)))
msgSubmit, err := govtypes.NewMsgSubmitProposal(proposal, deposit, from)
s.Require().NoError(err)
return msgSubmit
}

func (s *AnteTestSuite) getMsgGrantAllowance(from sdk.AccAddress) sdk.Msg {
spendLimit := sdk.NewCoins(sdk.NewInt64Coin(params.BaseDenom, 10000000))
threeHours := time.Now().Add(3 * time.Hour)
basic := &feegrant.BasicAllowance{
SpendLimit: spendLimit,
Expiration: &threeHours,
}

privkey2, _ := ethsecp256k1.GenerateKey()
grantee := sdk.AccAddress(privkey2.PubKey().Address())
msgGrant, err := feegrant.NewMsgGrantAllowance(basic, from, grantee)
s.Require().NoError(err)
return msgGrant
}

func (s *AnteTestSuite) getMsgCreateRollapp(from string, tokenless bool, metadata *rollapptypes.RollappMetadata) sdk.Msg {
genesisInfo := &rollapptypes.GenesisInfo{
Bech32Prefix: strings.ToLower(rand.Str(3)),
GenesisChecksum: "1234567890abcdefg",
InitialSupply: sdk.NewInt(1000),
NativeDenom: rollapptypes.DenomMetadata{
Display: "DEN",
Base: "aden",
Exponent: 18,
},
}

if metadata == nil {
metadata = &rollapptypes.RollappMetadata{
Website: "https://dymension.xyz",
Description: "Sample description",
LogoUrl: "https://dymension.xyz/logo.png",
Telegram: "https://t.me/rolly",
X: "https://x.dymension.xyz",
}
}

if tokenless {
genesisInfo.InitialSupply = math.ZeroInt()
genesisInfo.NativeDenom = rollapptypes.DenomMetadata{
Display: "",
Base: "",
Exponent: 1,
}
}

return &rollapptypes.MsgCreateRollapp{
Creator: from,
RollappId: "test_1000-1",
InitialSequencer: "*",
MinSequencerBond: rollapptypes.DefaultMinSequencerBondGlobalCoin,
Alias: strings.ToLower(rand.Str(7)),
VmType: rollapptypes.Rollapp_EVM,
GenesisInfo: genesisInfo,
Metadata: metadata,
}
}

func (s *AnteTestSuite) TestEIP712() {
s.SetupTestCheckTx(false)
privkey, _ := ethsecp256k1.GenerateKey()
acc := sdk.AccAddress(privkey.PubKey().Address())

amt := sdk.NewInt(10000).MulRaw(1e18)
err := bankutil.FundAccount(s.app.BankKeeper, s.ctx, privkey.PubKey().Address().Bytes(), sdk.NewCoins(sdk.NewCoin(params.BaseDenom, amt)))
s.Require().Nil(err)

from := acc

msgs := []sdk.Msg{
s.getMsgSend(from),
s.getMsgCreateRollapp(from.String(), false, nil), // native denom
s.getMsgCreateRollapp(from.String(), true, nil), // tokenless
s.getMsgGrant("/dymensionxyz.dymension.gamm.poolmodels.balancer.v1beta1.MsgCreateBalancerPool", from),
s.getMsgGrantAllowance(from),
s.getMsgSubmitProposal(from),
}

for _, msg := range msgs {
toTest := []sdk.Msg{msg}
err = s.DumpEIP712TypedData(from, toTest)
s.Require().NoError(err)
}
}

// FIXME: should iterate over all messages
func (suite *AnteTestSuite) DumpEIP712TypedData(from sdk.AccAddress, msgs []sdk.Msg) error {
txConfig := suite.clientCtx.TxConfig
coinAmount := sdk.NewCoin(params.DisplayDenom, sdk.NewInt(20))
fees := sdk.NewCoins(coinAmount)

pc, err := ethermint.ParseChainID(suite.ctx.ChainID())
suite.Require().NoError(err)
chainIDNum := pc.Uint64()

acc := suite.app.AccountKeeper.GetAccount(suite.ctx, from)
accNumber := acc.GetAccountNumber()
nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, from)
suite.Require().NoError(err)

suite.txBuilder = txConfig.NewTxBuilder()
builder, ok := suite.txBuilder.(authtx.ExtensionOptionsTxBuilder)
suite.Require().True(ok, "txBuilder could not be casted to authtx.ExtensionOptionsTxBuilder type")
builder.SetFeeAmount(fees)
builder.SetGasLimit(200000)

err = builder.SetMsgs(msgs...)
suite.Require().NoError(err)

txBytes := legacytx.StdSignBytes(
suite.ctx.ChainID(),
accNumber,
nonce,
0,
legacytx.StdFee{
Amount: fees,
Gas: 200000,
},
msgs, "", nil,
)

feeDelegation := &eip712.FeeDelegationOptions{
FeePayer: from,
}

data, err := eip712.LegacyWrapTxToTypedData(
suite.clientCtx.Codec,
chainIDNum,
msgs[0],
txBytes,
feeDelegation,
)
suite.Require().NoError(err)
_, _, err = apitypes.TypedDataAndHash(data)
suite.Require().NoError(err)

// Dump the json string to t.log
str, err := json.Marshal(data)
suite.Assert().NoError(err)
suite.T().Logf("typed data: %s", string(str))
return nil
}
4 changes: 3 additions & 1 deletion x/incentives/client/cli/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"testing"
"time"

"cosmossdk.io/math"
tmrand "github.com/cometbft/cometbft/libs/rand"
cometbftproto "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/baseapp"
Expand Down Expand Up @@ -36,7 +37,8 @@ func (suite *QueryTestSuite) CreateDefaultRollapp() string {
Alias: strings.ToLower(tmrand.Str(7)),
VmType: rollapptypes.Rollapp_EVM,
GenesisInfo: &rollapptypes.GenesisInfo{
Bech32Prefix: strings.ToLower(tmrand.Str(3)),
Bech32Prefix: strings.ToLower(tmrand.Str(3)),
InitialSupply: math.ZeroInt(),
},
}

Expand Down
27 changes: 16 additions & 11 deletions x/rollapp/keeper/msg_server_update_rollapp_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package keeper_test

import (
"cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
Expand Down Expand Up @@ -143,10 +144,10 @@ func (s *RollappTestSuite) TestUpdateRollapp() {
update: &types.MsgUpdateRollappInformation{
Owner: alice,
RollappId: rollappId,
GenesisInfo: &types.GenesisInfo{},
GenesisInfo: &types.GenesisInfo{InitialSupply: math.ZeroInt()},
},
mallete: func(expected *types.Rollapp) {
expected.GenesisInfo = types.GenesisInfo{InitialSupply: sdk.NewInt(0)}
expected.GenesisInfo = types.GenesisInfo{InitialSupply: math.ZeroInt()}
},
},
{
Expand Down Expand Up @@ -270,6 +271,7 @@ func (s *RollappTestSuite) TestUpdateRollappSealed() {
RollappId: rollappId,
GenesisInfo: &types.GenesisInfo{
GenesisChecksum: "new_checksum",
InitialSupply: math.ZeroInt(),
},
},
expError: types.ErrGenesisInfoSealed,
Expand All @@ -280,7 +282,8 @@ func (s *RollappTestSuite) TestUpdateRollappSealed() {
Owner: alice,
RollappId: rollappId,
GenesisInfo: &types.GenesisInfo{
Bech32Prefix: "new",
Bech32Prefix: "new",
InitialSupply: math.ZeroInt(),
},
},
expError: types.ErrGenesisInfoSealed,
Expand All @@ -296,6 +299,7 @@ func (s *RollappTestSuite) TestUpdateRollappSealed() {
Base: "aden",
Exponent: 18,
},
InitialSupply: sdk.NewInt(10000),
},
},
expError: types.ErrGenesisInfoSealed,
Expand Down Expand Up @@ -392,6 +396,7 @@ func (s *RollappTestSuite) TestUpdateRollappLaunched() {
RollappId: rollappId,
GenesisInfo: &types.GenesisInfo{
GenesisChecksum: "new_checksum",
InitialSupply: math.ZeroInt(),
},
},
expError: types.ErrImmutableFieldUpdateAfterLaunched,
Expand Down Expand Up @@ -426,7 +431,7 @@ func (s *RollappTestSuite) TestUpdateRollappLaunched() {
func (s *RollappTestSuite) TestUpdateRollappUpdateGenesisInfo() {
// we start with empty genesis info
gInfo := types.GenesisInfo{
InitialSupply: sdk.NewInt(0),
InitialSupply: math.ZeroInt(),
}

tests := []struct {
Expand All @@ -447,6 +452,7 @@ func (s *RollappTestSuite) TestUpdateRollappUpdateGenesisInfo() {
Base: "aden",
Exponent: 18,
},
InitialSupply: sdk.NewInt(10000),
},
},
mallete: func(expected *types.Rollapp) {
Expand All @@ -455,6 +461,7 @@ func (s *RollappTestSuite) TestUpdateRollappUpdateGenesisInfo() {
Base: "aden",
Exponent: 18,
}
expected.GenesisInfo.InitialSupply = sdk.NewInt(10000)
},
expError: nil,
},
Expand All @@ -466,6 +473,7 @@ func (s *RollappTestSuite) TestUpdateRollappUpdateGenesisInfo() {
InitialSequencer: initialSequencerAddress,
GenesisInfo: &types.GenesisInfo{
GenesisChecksum: "checksum",
InitialSupply: math.ZeroInt(),
},
},
mallete: func(expected *types.Rollapp) {
Expand All @@ -485,16 +493,13 @@ func (s *RollappTestSuite) TestUpdateRollappUpdateGenesisInfo() {
Base: "aden",
Exponent: 18,
},
InitialSupply: sdk.NewInt(0),
InitialSupply: math.ZeroInt(),
},
},
mallete: func(expected *types.Rollapp) {
expected.GenesisInfo.NativeDenom = types.DenomMetadata{
Display: "DEN",
Base: "aden",
Exponent: 18,
}
expected.GenesisInfo.InitialSupply = sdk.NewInt(0)
// we overwrite native denom with empty one when setting supply to 0
expected.GenesisInfo.NativeDenom = types.DenomMetadata{}
expected.GenesisInfo.InitialSupply = math.ZeroInt()
},
expError: nil,
},
Expand Down
4 changes: 4 additions & 0 deletions x/rollapp/keeper/rollapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ func (k Keeper) CheckAndUpdateRollappFields(ctx sdk.Context, update *types.MsgUp

if update.GenesisInfo != nil {
current.GenesisInfo = *update.GenesisInfo
// hotfix: if supply is zero, override the denom metadata with empty
if update.GenesisInfo.InitialSupply.IsZero() {
current.GenesisInfo.NativeDenom = types.DenomMetadata{}
}
}

if update.Metadata != nil && !update.Metadata.IsEmpty() {
Expand Down
3 changes: 2 additions & 1 deletion x/rollapp/types/genesis_info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"strings"
"testing"

"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"

Expand Down Expand Up @@ -65,7 +66,7 @@ func TestGenesisInfo_ValidateBasic(t *testing.T) {
msg: GenesisInfo{
Bech32Prefix: bech32Prefix,
GenesisChecksum: "checksum",
InitialSupply: sdk.NewInt(0),
InitialSupply: math.ZeroInt(),
},
err: nil,
},
Expand Down
4 changes: 4 additions & 0 deletions x/rollapp/types/message_create_rollapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ func (msg *MsgCreateRollapp) GetRollapp() Rollapp {
genInfo := GenesisInfo{}
if msg.GenesisInfo != nil {
genInfo = *msg.GenesisInfo
// hotfix: if supply is zero, override the denom metadata with empty
if genInfo.InitialSupply.IsZero() {
genInfo.NativeDenom = DenomMetadata{}
}
}
return NewRollapp(
msg.Creator,
Expand Down

0 comments on commit 8bdde21

Please sign in to comment.