diff --git a/CHANGELOG.md b/CHANGELOG.md index efc5f45f4..785c7f1e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ only on the "bankkeeper.BaseKeeper"'s gas consumption. Remove unnecessary argument in the `VerifyFee` function, which returns the token payment required based on the effective fee from the tx data. Improve documentation. +- [#2131](https://github.com/NibiruChain/nibiru/pull/2131) - fix(evm): proper block gas calculation in precompile calls #### Nibiru EVM | Before Audit 2 - 2024-12-06 diff --git a/x/evm/keeper/call_contract.go b/x/evm/keeper/call_contract.go index ad4ac90c7..d9dc889e8 100644 --- a/x/evm/keeper/call_contract.go +++ b/x/evm/keeper/call_contract.go @@ -108,14 +108,17 @@ func (k Keeper) CallContractWithInput( ctx, evmMsg, evm.NewNoOpTracer(), commit, evmCfg, txConfig, true, ) if err != nil { - // We don't know the actual gas used, so consuming the gas limit - k.ResetGasMeterAndConsumeGas(ctx, gasLimit) + k.ResetGasMeterAndConsumeGas(ctx, ctx.GasMeter().Limit()) err = errors.Wrap(err, "failed to apply ethereum core message") return } + blockGasUsed, errBlockGasUsed := k.AddToBlockGasUsed(ctx, evmResp.GasUsed) + if errBlockGasUsed != nil { + return nil, nil, errors.Wrap(errBlockGasUsed, "error adding transient gas used to block") + } + k.ResetGasMeterAndConsumeGas(ctx, blockGasUsed) if evmResp.Failed() { - k.ResetGasMeterAndConsumeGas(ctx, evmResp.GasUsed) if strings.Contains(evmResp.VmError, vm.ErrOutOfGas.Error()) { err = fmt.Errorf("gas required exceeds allowance (%d)", gasLimit) return @@ -130,12 +133,6 @@ func (k Keeper) CallContractWithInput( // Success, update block gas used and bloom filter if commit { - blockGasUsed, err := k.AddToBlockGasUsed(ctx, evmResp.GasUsed) - if err != nil { - k.ResetGasMeterAndConsumeGas(ctx, ctx.GasMeter().Limit()) - return nil, nil, errors.Wrap(err, "error adding transient gas used to block") - } - k.ResetGasMeterAndConsumeGas(ctx, blockGasUsed) k.updateBlockBloom(ctx, evmResp, uint64(txConfig.LogIndex)) // TODO: remove after migrating logs //err = k.EmitLogEvents(ctx, evmResp) diff --git a/x/evm/keeper/funtoken_from_coin_test.go b/x/evm/keeper/funtoken_from_coin_test.go index ed3f47c10..f790ca896 100644 --- a/x/evm/keeper/funtoken_from_coin_test.go +++ b/x/evm/keeper/funtoken_from_coin_test.go @@ -255,6 +255,8 @@ func (s *FunTokenFromCoinSuite) TestConvertCoinToEvmAndBack() { s.Require().NoError(err) s.Require().Equal("0", balance.String()) + deps.ResetGasMeter() + s.T().Log("sad: Convert more erc-20 to back to bank coin, insufficient funds") _, err = deps.EvmKeeper.CallContract( deps.Ctx, diff --git a/x/evm/precompile/funtoken_test.go b/x/evm/precompile/funtoken_test.go index 7645a26e5..12cce737b 100644 --- a/x/evm/precompile/funtoken_test.go +++ b/x/evm/precompile/funtoken_test.go @@ -171,6 +171,8 @@ func (s *FuntokenSuite) TestHappyPath() { sdk.NewCoins(sdk.NewCoin(s.funtoken.BankDenom, sdk.NewInt(69_420))), )) + deps.ResetGasMeter() + s.Run("IFunToken.bankBalance", func() { s.Require().NotEmpty(funtoken.BankDenom) evmResp, err := deps.EvmKeeper.CallContract( @@ -222,7 +224,6 @@ func (s *FuntokenSuite) TestHappyPath() { input, err := embeds.SmartContract_FunToken.ABI.Pack(string(precompile.FunTokenMethod_sendToBank), callArgs...) s.NoError(err) - deps.ResetGasMeter() _, ethTxResp, err := evmtest.CallContractTx( &deps, precompile.PrecompileAddr_FunToken, @@ -242,7 +243,6 @@ func (s *FuntokenSuite) TestHappyPath() { s.Equal(sdk.NewInt(420).String(), deps.App.BankKeeper.GetBalance(deps.Ctx, randomAcc, funtoken.BankDenom).Amount.String(), ) - s.deps.ResetGasMeter() s.Require().NotNil(deps.EvmKeeper.Bank.StateDB) s.T().Log("Parse the response contract addr and response bytes") @@ -255,6 +255,8 @@ func (s *FuntokenSuite) TestHappyPath() { s.NoError(err) s.Require().Equal("420", sentAmt.String()) + deps.ResetGasMeter() + s.Run("IFuntoken.balance", func() { evmResp, err := deps.EvmKeeper.CallContract( deps.Ctx,