Skip to content

Commit

Permalink
Problem: base fee conversion could panic on overflow (backport #433) (#…
Browse files Browse the repository at this point in the history
…435)

* Problem: base fee conversion could panic on overflow (#433)

* prevent integer overflow

use sdkmath.MaxBitLen

cleanup

* changelog

---------

Co-authored-by: Brian Luk <brian6.dev@gmail.com>

* Update CHANGELOG.md

Signed-off-by: yihuang <huang@crypto.com>

---------

Signed-off-by: yihuang <huang@crypto.com>
Co-authored-by: yihuang <huang@crypto.com>
Co-authored-by: Brian Luk <brian6.dev@gmail.com>
  • Loading branch information
3 people authored Mar 26, 2024
1 parent 426480e commit 8213099
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 3 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ Ref: https://keepachangelog.com/en/1.0.0/

## Unreleased

### Bug Fixes

- (feemarket) [#433](https://github.com/crypto-org-chain/ethermint/pull/433) Fix sdk int conversion panic with baseFee.

### Features

## v0.21.x-cronos

### Features

* (rpc) [#1682](https://github.com/evmos/ethermint/pull/1682) Add config for maximum number of bytes returned from eth_call.
Expand Down
35 changes: 33 additions & 2 deletions types/int.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,23 @@ import (
fmt "fmt"
math "math"
"math/big"
"math/bits"

errorsmod "cosmossdk.io/errors"
sdkmath "cosmossdk.io/math"
errortypes "github.com/cosmos/cosmos-sdk/types/errors"
)

const maxBitLen = 256
const (
maxWordLen = sdkmath.MaxBitLen / bits.UintSize
)

var MaxInt256 *big.Int

func init() {
var tmp big.Int
MaxInt256 = tmp.Lsh(big.NewInt(1), sdkmath.MaxBitLen).Sub(&tmp, big.NewInt(1))
}

// SafeInt64 checks for overflows while casting a uint64 to int64 value.
func SafeInt64(value uint64) (int64, error) {
Expand All @@ -52,7 +62,28 @@ func SafeNewIntFromBigInt(i *big.Int) (sdkmath.Int, error) {
return sdkmath.NewIntFromBigInt(i), nil
}

// SaturatedNewInt constructs Int from big.Int, truncate if more than 256bits
func SaturatedNewInt(i *big.Int) sdkmath.Int {
if !IsValidInt256(i) {
i = MaxInt256
}
return sdkmath.NewIntFromBigInt(i)
}

// IsValidInt256 check the bound of 256 bit number
func IsValidInt256(i *big.Int) bool {
return i == nil || i.BitLen() <= maxBitLen
return i == nil || !bigIntOverflows(i)
}

// check if the big int overflows,
// NOTE: copied from cosmos-sdk.
func bigIntOverflows(i *big.Int) bool {
// overflow is defined as i.BitLen() > MaxBitLen
// however this check can be expensive when doing many operations.
// So we first check if the word length is greater than maxWordLen.
// However the most significant word could be zero, hence we still do the bitlen check.
if len(i.Bits()) > maxWordLen {
return i.BitLen() > sdkmath.MaxBitLen
}
return false
}
18 changes: 18 additions & 0 deletions types/int_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package types

import (
"math/big"
"testing"

sdkmath "cosmossdk.io/math"
"github.com/stretchr/testify/require"
)

func TestMaxInt256(t *testing.T) {
maxInt256Plus1 := new(big.Int).Add(MaxInt256, big.NewInt(1))
require.Equal(t, sdkmath.MaxBitLen, MaxInt256.BitLen())
require.Equal(t, sdkmath.MaxBitLen+1, maxInt256Plus1.BitLen())

require.True(t, IsValidInt256(MaxInt256))
require.False(t, IsValidInt256(maxInt256Plus1))
}
3 changes: 2 additions & 1 deletion x/feemarket/keeper/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package keeper
import (
"math/big"

ethermint "github.com/evmos/ethermint/types"
"github.com/evmos/ethermint/x/feemarket/types"

sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -79,7 +80,7 @@ func (k Keeper) GetBaseFee(ctx sdk.Context) *big.Int {
// SetBaseFee set's the base fee in the store
func (k Keeper) SetBaseFee(ctx sdk.Context, baseFee *big.Int) {
params := k.GetParams(ctx)
params.BaseFee = sdk.NewIntFromBigInt(baseFee)
params.BaseFee = ethermint.SaturatedNewInt(baseFee)
err := k.SetParams(ctx, params)
if err != nil {
return
Expand Down

0 comments on commit 8213099

Please sign in to comment.