Skip to content

Commit

Permalink
fix: add fee field manipulation check (#98)
Browse files Browse the repository at this point in the history
* add fee field manipulation check

* add codcov ignore

* add fee manipulation checker
  • Loading branch information
beer-1 authored Nov 4, 2024
1 parent 126224b commit f0b8db3
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 10 deletions.
1 change: 1 addition & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ ignore:
- "**/test_utils.go"
- "**/module.go"
- "x/ibc/testing"
- "**/contracts"
17 changes: 12 additions & 5 deletions x/evm/keeper/txutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ func (u *TxUtils) ConvertCosmosTxToEthereumTx(ctx context.Context, sdkTx sdk.Tx)
return nil, nil, nil
}

fees := authTx.GetFee()
feeAmount := authTx.GetFee()
params, err := u.Params.Get(ctx)
if err != nil {
return nil, nil, err
Expand All @@ -225,7 +225,7 @@ func (u *TxUtils) ConvertCosmosTxToEthereumTx(ctx context.Context, sdkTx sdk.Tx)
return nil, nil, err
}

if !(len(fees) == 0 || (len(fees) == 1 && fees[0].Denom == params.FeeDenom)) {
if !(len(feeAmount) == 0 || (len(feeAmount) == 1 && feeAmount[0].Denom == params.FeeDenom)) {
return nil, nil, nil
}

Expand Down Expand Up @@ -258,7 +258,7 @@ func (u *TxUtils) ConvertCosmosTxToEthereumTx(ctx context.Context, sdkTx sdk.Tx)
} else if len(sigData.Signature) == 64 {
v, r, s = []byte{}, sigData.Signature[:32], sigData.Signature[32:64]
} else {
return nil, nil, nil
return nil, nil, types.ErrTxConversionFailed.Wrap("invalid signature length")
}

gasFeeCap, ok := new(big.Int).SetString(md.GasFeeCap, 10)
Expand All @@ -271,6 +271,13 @@ func (u *TxUtils) ConvertCosmosTxToEthereumTx(ctx context.Context, sdkTx sdk.Tx)
return nil, nil, err
}

// check if the fee amount is correctly converted
computedFeeAmount := sdk.NewCoins(sdk.NewCoin(params.FeeDenom, math.NewIntFromBigInt(computeGasFeeAmount(gasFeeCap, gas, decimals))))
if !feeAmount.Equal(computedFeeAmount) {
u.Logger(ctx).Error("fee amount manipulation detected", "expected", computedFeeAmount, "actual", feeAmount)
return nil, nil, types.ErrTxConversionFailed.Wrap("fee amount manipulation detected")
}

var to *common.Address
var input []byte
var value *big.Int
Expand Down Expand Up @@ -397,13 +404,13 @@ func (u *TxUtils) IsEthereumTx(ctx context.Context, sdkTx sdk.Tx) (bool, error)
return false, nil
}

fees := authTx.GetFee()
feeAmount := authTx.GetFee()
params, err := u.Params.Get(ctx)
if err != nil {
return false, err
}

if !(len(fees) == 0 || (len(fees) == 1 && fees[0].Denom == params.FeeDenom)) {
if !(len(feeAmount) == 0 || (len(feeAmount) == 1 && feeAmount[0].Denom == params.FeeDenom)) {
return false, nil
}

Expand Down
31 changes: 26 additions & 5 deletions x/evm/keeper/txutils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import (
"github.com/stretchr/testify/require"

"cosmossdk.io/math"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"

"github.com/cosmos/cosmos-sdk/client"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
coretypes "github.com/ethereum/go-ethereum/core/types"
Expand Down Expand Up @@ -112,7 +112,8 @@ func Test_DynamicFeeTxConversion(t *testing.T) {
})

authTx := sdkTx.(authsigning.Tx)
require.Equal(t, authTx.GetFee(), sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewIntFromBigInt(feeAmount).AddRaw(1))))
expectedFeeAmount := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewIntFromBigInt(feeAmount).AddRaw(1)))
require.Equal(t, authTx.GetFee(), expectedFeeAmount)

sigs, err := authTx.GetSignaturesV2()
require.NoError(t, err)
Expand All @@ -137,6 +138,12 @@ func Test_DynamicFeeTxConversion(t *testing.T) {
ethTx2, _, err := keeper.NewTxUtils(&input.EVMKeeper).ConvertCosmosTxToEthereumTx(ctx, sdkTx)
require.NoError(t, err)
EqualEthTransaction(t, signedTx, ethTx2)

// manipulate the fee amount
txBuilder := sdkTx.(client.TxBuilder)
txBuilder.SetFeeAmount(expectedFeeAmount.Add(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(1))))
_, _, err = keeper.NewTxUtils(&input.EVMKeeper).ConvertCosmosTxToEthereumTx(ctx, txBuilder.GetTx())
require.ErrorIs(t, err, types.ErrTxConversionFailed)
}

func Test_AccessTxConversion(t *testing.T) {
Expand Down Expand Up @@ -298,7 +305,8 @@ func Test_AccessTxConversion(t *testing.T) {
})

authTx = sdkTx.(authsigning.Tx)
require.Equal(t, authTx.GetFee(), sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewIntFromBigInt(feeAmount).AddRaw(1))))
expectedFeeAmount := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewIntFromBigInt(feeAmount).AddRaw(1)))
require.Equal(t, authTx.GetFee(), expectedFeeAmount)

sigs, err = authTx.GetSignaturesV2()
require.NoError(t, err)
Expand All @@ -323,6 +331,12 @@ func Test_AccessTxConversion(t *testing.T) {
ethTx2, _, err = keeper.NewTxUtils(&input.EVMKeeper).ConvertCosmosTxToEthereumTx(ctx, sdkTx)
require.NoError(t, err)
EqualEthTransaction(t, signedTx, ethTx2)

// manipulate the fee amount
txBuilder := sdkTx.(client.TxBuilder)
txBuilder.SetFeeAmount(expectedFeeAmount.Add(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(1))))
_, _, err = keeper.NewTxUtils(&input.EVMKeeper).ConvertCosmosTxToEthereumTx(ctx, txBuilder.GetTx())
require.ErrorIs(t, err, types.ErrTxConversionFailed)
}

func Test_LegacyTxConversion(t *testing.T) {
Expand Down Expand Up @@ -394,7 +408,8 @@ func Test_LegacyTxConversion(t *testing.T) {
})

authTx := sdkTx.(authsigning.Tx)
require.Equal(t, authTx.GetFee(), sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewIntFromBigInt(feeAmount).AddRaw(1))))
expectedFeeAmount := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewIntFromBigInt(feeAmount).AddRaw(1)))
require.Equal(t, authTx.GetFee(), expectedFeeAmount)

sigs, err := authTx.GetSignaturesV2()
require.NoError(t, err)
Expand All @@ -419,6 +434,12 @@ func Test_LegacyTxConversion(t *testing.T) {
ethTx2, _, err := keeper.NewTxUtils(&input.EVMKeeper).ConvertCosmosTxToEthereumTx(ctx, sdkTx)
require.NoError(t, err)
EqualEthTransaction(t, signedTx, ethTx2)

// manipulate the fee amount
txBuilder := sdkTx.(client.TxBuilder)
txBuilder.SetFeeAmount(expectedFeeAmount.Add(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(1))))
_, _, err = keeper.NewTxUtils(&input.EVMKeeper).ConvertCosmosTxToEthereumTx(ctx, txBuilder.GetTx())
require.ErrorIs(t, err, types.ErrTxConversionFailed)
}

func Test_IsEthereumTx(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions x/evm/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ var (
ErrFailedToGetERC20WrapperAddr = errorsmod.Register(ModuleName, 28, "Failed to get ERC20 wrapper address")
ErrInvalidNumRetainBlockHashes = errorsmod.Register(ModuleName, 29, "Invalid num retain block hashes")
ErrExceedMaxRecursiveDepth = errorsmod.Register(ModuleName, 30, "Exceed max recursive depth")
ErrTxConversionFailed = errorsmod.Register(ModuleName, 31, "Tx conversion failed")
)

func NewRevertError(revert []byte) error {
Expand Down

0 comments on commit f0b8db3

Please sign in to comment.