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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
- [\#800](https://github.com/cosmos/evm/pull/800) Fix denom exponent validation in virtual fee deduct in vm module.
- [\#817](https://github.com/cosmos/evm/pull/817) Align GetCoinbaseAddress to handle empty proposer address in contexts like CheckTx where proposer doesn't exist.
- [\#816](https://github.com/cosmos/evm/pull/816) Avoid nil pointer when RPC requests execute before evmCoinInfo initialization in PreBlock with defaultEvmCoinInfo fallback.
- [\#828](https://github.com/cosmos/evm/pull/828) Validate decimals before conversion to prevent panic when coininfo is missing in historical queries.

## v0.5.0

Expand Down
18 changes: 14 additions & 4 deletions x/vm/wrappers/feemarket.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,21 @@ func NewFeeMarketWrapper(
// GetBaseFee returns the base fee converted to 18 decimals.
func (w FeeMarketWrapper) GetBaseFee(ctx sdk.Context, decimals types.Decimals) *big.Int {
baseFee := w.FeeMarketKeeper.GetBaseFee(ctx)
if baseFee.IsNil() {
return nil
if baseFee.IsNil() || baseFee.BigInt() == nil {
return big.NewInt(0)
}

return baseFee.MulInt(decimals.ConversionFactor()).TruncateInt().BigInt()
if err := decimals.Validate(); err != nil {
return big.NewInt(0)
}
conv := decimals.ConversionFactor()
if conv.BigInt() == nil {
return big.NewInt(0)
}
converted := baseFee.MulInt(conv).TruncateInt().BigInt()
if converted == nil {
return big.NewInt(0)
}
return converted
}

// CalculateBaseFee returns the calculated base fee converted to 18 decimals.
Expand Down
54 changes: 44 additions & 10 deletions x/vm/wrappers/feemarket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func TestGetBaseFee(t *testing.T) {
{
name: "success - nil base fee",
coinInfo: testconstants.ExampleChainCoinInfo[testconstants.SixDecimalsChainID],
expResult: nil,
expResult: big.NewInt(0),
mockSetup: func(mfk *testutil.MockFeeMarketKeeper) {
mfk.EXPECT().
GetBaseFee(gomock.Any()).
Expand Down Expand Up @@ -85,24 +85,58 @@ func TestGetBaseFee(t *testing.T) {
Return(sdkmath.LegacyNewDecWithPrec(1, 13)) // multiplied by 1e12 is still less than 1
},
},
{
name: "defensive - zero decimals returns zero without panic",
coinInfo: evmtypes.EvmCoinInfo{
Denom: "aevmos",
ExtendedDenom: "aevmos",
DisplayDenom: "evmos",
Decimals: 0, // invalid/uninitialized
},
expResult: big.NewInt(0),
mockSetup: func(mfk *testutil.MockFeeMarketKeeper) {
mfk.EXPECT().
GetBaseFee(gomock.Any()).
Return(sdkmath.LegacyNewDec(1e18))
},
},
{
name: "defensive - invalid decimals (19) returns zero without panic",
coinInfo: evmtypes.EvmCoinInfo{
Denom: "aevmos",
ExtendedDenom: "aevmos",
DisplayDenom: "evmos",
Decimals: 19, // exceeds max supported
},
expResult: big.NewInt(0),
mockSetup: func(mfk *testutil.MockFeeMarketKeeper) {
mfk.EXPECT().
GetBaseFee(gomock.Any()).
Return(sdkmath.LegacyNewDec(1e18))
},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// Setup EVM configurator to have access to the EVM coin info.
configurator := evmtypes.NewEVMConfigurator()
configurator.ResetTestConfig()
err := configurator.WithEVMCoinInfo(tc.coinInfo).Configure()
require.NoError(t, err, "failed to configure EVMConfigurator")

ctrl := gomock.NewController(t)
mockFeeMarketKeeper := testutil.NewMockFeeMarketKeeper(ctrl)
tc.mockSetup(mockFeeMarketKeeper)

feeMarketWrapper := wrappers.NewFeeMarketWrapper(mockFeeMarketKeeper)
result := feeMarketWrapper.GetBaseFee(sdk.Context{}, evmtypes.Decimals(tc.coinInfo.Decimals))

require.Equal(t, tc.expResult, result)
// skip EVMConfigurator for defensive cases
if tc.coinInfo.Decimals == 0 || tc.coinInfo.Decimals > 18 {
result := feeMarketWrapper.GetBaseFee(sdk.Context{}, evmtypes.Decimals(tc.coinInfo.Decimals))
require.Equal(t, tc.expResult, result)
} else {
// Setup EVM configurator to have access to the EVM coin info.
configurator := evmtypes.NewEVMConfigurator()
configurator.ResetTestConfig()
err := configurator.WithEVMCoinInfo(tc.coinInfo).Configure()
require.NoError(t, err, "failed to configure EVMConfigurator")
result := feeMarketWrapper.GetBaseFee(sdk.Context{}, evmtypes.Decimals(tc.coinInfo.Decimals))
require.Equal(t, tc.expResult, result)
}
})
}
}
Expand Down
Loading