Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,6 @@ require (
replace (
// need this replace when importing cosmos/rosetta pkg
cosmossdk.io/core => cosmossdk.io/core v0.11.0
// need this replace to pick up the store changes (Copy func) in our cosmos-sdk branch
//todo: merge this sdk release
cosmossdk.io/store => github.com/cosmos/cosmos-sdk/store v1.1.2-0.20250319183239-53dea340efc7

// use cosmos fork of keyring
github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.5.0 h1:sbOASxee9Zxdjd6OkzogvBZ25/hP929vdcYcBJQbkLc=
cosmossdk.io/math v1.5.0/go.mod h1:AAwwBmUhqtk2nlku174JwSll+/DepUXW3rWIXN5q+Nw=
cosmossdk.io/store v1.1.1 h1:NA3PioJtWDVU7cHHeyvdva5J/ggyLDkyH0hGHl2804Y=
cosmossdk.io/store v1.1.1/go.mod h1:8DwVTz83/2PSI366FERGbWSH7hL6sB7HbYp8bqksNwM=
cosmossdk.io/tools/confix v0.1.2 h1:2hoM1oFCNisd0ltSAAZw2i4ponARPmlhuNu3yy0VwI4=
cosmossdk.io/tools/confix v0.1.2/go.mod h1:7XfcbK9sC/KNgVGxgLM0BrFbVcR/+6Dg7MFfpx7duYo=
cosmossdk.io/x/evidence v0.1.1 h1:Ks+BLTa3uftFpElLTDp9L76t2b58htjVbSZ86aoK/E4=
Expand Down Expand Up @@ -392,8 +394,6 @@ github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+R
github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec=
github.com/cosmos/cosmos-sdk v0.50.13-0.20250319183239-53dea340efc7 h1:zoOAawQLQXLg+HuSOfmuwtTMC4Qovc23a60+xfoHKUw=
github.com/cosmos/cosmos-sdk v0.50.13-0.20250319183239-53dea340efc7/go.mod h1:hrWEFMU1eoXqLJeE6VVESpJDQH67FS1nnMrQIjO2daw=
github.com/cosmos/cosmos-sdk/store v1.1.2-0.20250319183239-53dea340efc7 h1:7EBHeRE/Kmba2A9JlJ9/sOlHhmEHggyyWRD/uGccnC8=
github.com/cosmos/cosmos-sdk/store v1.1.2-0.20250319183239-53dea340efc7/go.mod h1:8DwVTz83/2PSI366FERGbWSH7hL6sB7HbYp8bqksNwM=
github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY=
github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw=
github.com/cosmos/go-ethereum v1.10.26-evmos-rc4.0.20250402013457-cf9d288f0147 h1:Hm9aFN6PBpc4YV4JZXJu4cLrOsVguDd9QwfnDmb5LGg=
Expand Down
194 changes: 194 additions & 0 deletions precompiles/distribution/distribution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

chainutil "github.com/cosmos/evm/evmd/testutil"
"github.com/cosmos/evm/precompiles/distribution"
"github.com/cosmos/evm/precompiles/testutil"
"github.com/cosmos/evm/testutil/constants"
evmtypes "github.com/cosmos/evm/x/vm/types"

Expand Down Expand Up @@ -276,3 +277,196 @@ func (s *PrecompileTestSuite) TestRun() {
})
}
}

func (s *PrecompileTestSuite) TestCMS() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that staking_test.go includes failure cases (like gas too low or invalid method inputs) to validate negative paths.
Would it make sense to include a few similar test cases here as well?

var (
ctx sdk.Context
err error
)
testcases := []struct {
name string
malleate func() (common.Address, []byte)
expPass bool
errContains string
}{
{
name: "pass - set withdraw address transaction",
malleate: func() (common.Address, []byte) {
valAddr, err := sdk.ValAddressFromBech32(s.network.GetValidators()[0].OperatorAddress)
s.Require().NoError(err)
val, _ := s.network.App.StakingKeeper.GetValidator(ctx, valAddr)
coins := sdk.NewCoins(sdk.NewCoin(constants.ExampleAttoDenom, math.NewInt(1e18)))
s.Require().NoError(s.network.App.DistrKeeper.AllocateTokensToValidator(ctx, val, sdk.NewDecCoinsFromCoins(coins...)))

input, err := s.precompile.Pack(
distribution.SetWithdrawAddressMethod,
s.keyring.GetAddr(0),
s.keyring.GetAddr(0).String(),
)
s.Require().NoError(err, "failed to pack input")
return s.keyring.GetAddr(0), input
},
expPass: true,
},
{
name: "pass - withdraw validator commissions transaction",
malleate: func() (common.Address, []byte) {
hexAddr := common.Bytes2Hex(s.keyring.GetAddr(0).Bytes())
valAddr, err := sdk.ValAddressFromHex(hexAddr)
s.Require().NoError(err)
caller := common.BytesToAddress(valAddr)

commAmt := math.LegacyNewDecWithPrec(1000000000000000000, 1)
valCommission := sdk.DecCoins{sdk.NewDecCoinFromDec(constants.ExampleAttoDenom, commAmt)}
// set outstanding rewards
s.Require().NoError(s.network.App.DistrKeeper.SetValidatorOutstandingRewards(ctx, valAddr, types.ValidatorOutstandingRewards{Rewards: valCommission}))
// set commission
s.Require().NoError(s.network.App.DistrKeeper.SetValidatorAccumulatedCommission(ctx, valAddr, types.ValidatorAccumulatedCommission{Commission: valCommission}))

// set distribution module account balance which pays out the rewards
coins := sdk.NewCoins(sdk.NewCoin(s.bondDenom, commAmt.RoundInt()))
err = s.mintCoinsForDistrMod(ctx, coins)
s.Require().NoError(err, "failed to fund distr module account")

input, err := s.precompile.Pack(
distribution.WithdrawValidatorCommissionMethod,
valAddr.String(),
)
s.Require().NoError(err, "failed to pack input")
return caller, input
},
expPass: true,
},
{
name: "pass - withdraw delegator rewards transaction",
malleate: func() (common.Address, []byte) {
val := s.network.GetValidators()[0]
ctx, err = s.prepareStakingRewards(
ctx,
stakingRewards{
Delegator: s.keyring.GetAccAddr(0),
Validator: val,
RewardAmt: testRewardsAmt,
},
)
s.Require().NoError(err, "failed to prepare staking rewards")

input, err := s.precompile.Pack(
distribution.WithdrawDelegatorRewardsMethod,
s.keyring.GetAddr(0),
val.OperatorAddress,
)
s.Require().NoError(err, "failed to pack input")

return s.keyring.GetAddr(0), input
},
expPass: true,
},
{
name: "pass - claim rewards transaction",
malleate: func() (common.Address, []byte) {
ctx, err = s.prepareStakingRewards(
ctx,
stakingRewards{
Delegator: s.keyring.GetAccAddr(0),
Validator: s.network.GetValidators()[0],
RewardAmt: testRewardsAmt,
},
)
s.Require().NoError(err, "failed to prepare staking rewards")

input, err := s.precompile.Pack(
distribution.ClaimRewardsMethod,
s.keyring.GetAddr(0),
uint32(2),
)
s.Require().NoError(err, "failed to pack input")

return s.keyring.GetAddr(0), input
},
expPass: true,
},
{
name: "pass - fund community pool transaction",
malleate: func() (common.Address, []byte) {
input, err := s.precompile.Pack(
distribution.FundCommunityPoolMethod,
s.keyring.GetAddr(0),
big.NewInt(1e18),
)
s.Require().NoError(err, "failed to pack input")

return s.keyring.GetAddr(0), input
},
expPass: true,
},
{
name: "pass - fund community pool transaction",
malleate: func() (common.Address, []byte) {
input, err := s.precompile.Pack(
distribution.FundCommunityPoolMethod,
s.keyring.GetAddr(0),
big.NewInt(1e18),
)
s.Require().NoError(err, "failed to pack input")

return s.keyring.GetAddr(0), input
},
expPass: true,
},
}

for _, tc := range testcases {
s.Run(tc.name, func() {
// setup basic test suite
s.SetupTest()
ctx = s.network.GetContext()
cms := &testutil.TrackingMultiStore{
Store: s.network.App.BaseApp.CommitMultiStore().CacheMultiStore(),
Writes: 0,
HistoricalStores: nil,
}
ctx = ctx.WithMultiStore(cms)
baseFee := s.network.App.EVMKeeper.GetBaseFee(ctx)

// malleate testcase
caller, input := tc.malleate()
contract := vm.NewPrecompile(vm.AccountRef(caller), s.precompile, big.NewInt(0), uint64(1e6))

contractAddr := contract.Address()
// Build and sign Ethereum transaction
txArgs := evmtypes.EvmTxArgs{
Input: input,
ChainID: evmtypes.GetEthChainConfig().ChainID,
Nonce: 0,
To: &contractAddr,
Amount: nil,
GasLimit: 1000000,
GasPrice: chainutil.ExampleMinGasPrices.BigInt(),
GasFeeCap: baseFee,
GasTipCap: big.NewInt(1),
Accesses: &gethtypes.AccessList{},
}
msgEthereumTx, err := s.factory.GenerateMsgEthereumTx(s.keyring.GetPrivKey(0), txArgs)
s.Require().NoError(err, "failed to generate Ethereum message")

signedMsg, err := s.factory.SignMsgEthereumTx(s.keyring.GetPrivKey(0), msgEthereumTx)
s.Require().NoError(err, "failed to sign Ethereum message")

resp, err := s.network.App.EVMKeeper.EthereumTx(ctx, &signedMsg)

// Check results
if tc.expPass {
s.Require().NoError(err, "expected no error when running the precompile")
s.Require().NotNil(resp.Ret, "expected returned bytes not to be nil")
testutil.ValidateWrites(s.T(), cms, 2)
} else {
s.Require().Error(err, "expected error to be returned when running the precompile")
s.Require().Nil(resp.Ret, "expected returned bytes to be nil")
s.Require().ErrorContains(err, tc.errContains)
// Writes once because of gas usage
testutil.ValidateWrites(s.T(), cms, 1)
}
})
}
}
32 changes: 29 additions & 3 deletions precompiles/staking/setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,17 @@ import (
"github.com/stretchr/testify/suite"

"github.com/cosmos/evm/precompiles/staking"
testconstants "github.com/cosmos/evm/testutil/constants"
"github.com/cosmos/evm/testutil/integration/os/factory"
"github.com/cosmos/evm/testutil/integration/os/grpc"
testkeyring "github.com/cosmos/evm/testutil/integration/os/keyring"
"github.com/cosmos/evm/testutil/integration/os/network"

sdkmath "cosmossdk.io/math"

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

type PrecompileTestSuite struct {
Expand All @@ -20,8 +27,9 @@ type PrecompileTestSuite struct {
grpcHandler grpc.Handler
keyring testkeyring.Keyring

bondDenom string
precompile *staking.Precompile
bondDenom string
precompile *staking.Precompile
customGenesis bool
}

func TestPrecompileUnitTestSuite(t *testing.T) {
Expand All @@ -30,8 +38,26 @@ func TestPrecompileUnitTestSuite(t *testing.T) {

func (s *PrecompileTestSuite) SetupTest() {
keyring := testkeyring.New(2)
nw := network.NewUnitTestNetwork(
customGenesis := network.CustomGenesisState{}
// mint some coin to fee collector
coins := sdk.NewCoins(sdk.NewCoin(testconstants.ExampleAttoDenom, sdkmath.NewInt(1000000000000000)))
balances := []banktypes.Balance{
{
Address: authtypes.NewModuleAddress(authtypes.FeeCollectorName).String(),
Coins: coins,
},
}
bankGenesis := banktypes.DefaultGenesisState()
bankGenesis.Balances = balances
customGenesis[banktypes.ModuleName] = bankGenesis
cfgOpts := []network.ConfigOption{
network.WithPreFundedAccounts(keyring.GetAllAccAddrs()...),
}
if s.customGenesis {
cfgOpts = append(cfgOpts, network.WithCustomGenesis(customGenesis))
}
nw := network.NewUnitTestNetwork(
cfgOpts...,
)
grpcHandler := grpc.NewIntegrationHandler(nw)
txFactory := factory.New(nw, grpcHandler)
Expand Down
Loading
Loading