Skip to content

Commit

Permalink
remove new bank keeper
Browse files Browse the repository at this point in the history
  • Loading branch information
Unique-Divine committed Oct 29, 2024
1 parent 04a6897 commit 4184906
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 239 deletions.
23 changes: 8 additions & 15 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,21 +70,14 @@ consistent setup and dynamic gas calculations, addressing the following tickets.
- [#2089](https://github.com/NibiruChain/nibiru/pull/2089) - better handling of gas consumption within erc20 contract execution
- [#2091](https://github.com/NibiruChain/nibiru/pull/2091) - feat(evm): add fun token creation fee validation
- [#2094](https://github.com/NibiruChain/nibiru/pull/2094) - fix(evm): Following
from the changs in #2086, this pull request implements two critical security
fixes.
1. First, we add new `JournalChange` struct that saves a deep copy of the
state multi store before each state-modifying, Nibiru-specific precompiled
contract is called (`OnRunStart`). Additionally, we commit the `StateDB` there
as well. This guarantees that the non-EVM and EVM state will be in sync even
if there are complex, multi-step Ethereum transactions, such as in the case of
an EthereumTx that influences the `StateDB`, then calls a precompile that also
changes non-EVM state, and then EVM reverts inside of a try-catch.
2. Second, the solution from #2086 that records NIBI (ether) transfers on the
`StateDB` during precompiled contract calls is generalized as
`NibiruBankKeeper`, which is struct extension of the `bankkeeper.BaseKeeper`
that is used throughout the Nibiru base application. The `NibiruBankKeeper`
holds a reference to the current EVM `StateDB` if there is one and records
balance changes in wei as journal changes automatically.
from the changs in #2086, this pull request implements a new `JournalChange`
struct that saves a deep copy of the state multi store before each
state-modifying, Nibiru-specific precompiled contract is called (`OnRunStart`).
Additionally, we commit the `StateDB` there as well. This guarantees that the
non-EVM and EVM state will be in sync even if there are complex, multi-step
Ethereum transactions, such as in the case of an EthereumTx that influences the
`StateDB`, then calls a precompile that also changes non-EVM state, and then EVM
reverts inside of a try-catch.


#### Nibiru EVM | Before Audit 1 - 2024-10-18
Expand Down
15 changes: 2 additions & 13 deletions app/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,24 +264,13 @@ func (app *NibiruApp) InitKeepers(
govModuleAddr,
)

app.bankBaseKeeper = bankkeeper.NewBaseKeeper(
app.BankKeeper = bankkeeper.NewBaseKeeper(
appCodec,
keys[banktypes.StoreKey],
app.AccountKeeper,
BlockedAddresses(),
govModuleAddr,
)
nibiruBankKeeper := evmkeeper.NibiruBankKeeper{
BaseKeeper: bankkeeper.NewBaseKeeper(
appCodec,
keys[banktypes.StoreKey],
app.AccountKeeper,
BlockedAddresses(),
govModuleAddr,
),
StateDB: nil,
}
app.BankKeeper = nibiruBankKeeper

app.StakingKeeper = stakingkeeper.NewKeeper(
appCodec,
Expand Down Expand Up @@ -384,7 +373,7 @@ func (app *NibiruApp) InitKeepers(
tkeys[evm.TransientKey],
authtypes.NewModuleAddress(govtypes.ModuleName),
app.AccountKeeper,
&nibiruBankKeeper,
app.BankKeeper,
app.StakingKeeper,
cast.ToString(appOpts.Get("evm.tracer")),
)
Expand Down
163 changes: 0 additions & 163 deletions x/evm/keeper/bank_extension.go

This file was deleted.

5 changes: 3 additions & 2 deletions x/evm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
gethcommon "github.com/ethereum/go-ethereum/common"

"github.com/NibiruChain/nibiru/v2/app/appconst"
Expand All @@ -40,7 +41,7 @@ type Keeper struct {
// this should be the x/gov module account.
authority sdk.AccAddress

bankKeeper *NibiruBankKeeper
bankKeeper bankkeeper.Keeper
accountKeeper evm.AccountKeeper
stakingKeeper evm.StakingKeeper

Expand All @@ -63,7 +64,7 @@ func NewKeeper(
storeKey, transientKey storetypes.StoreKey,
authority sdk.AccAddress,
accKeeper evm.AccountKeeper,
bankKeeper *NibiruBankKeeper,
bankKeeper bankkeeper.Keeper,
stakingKeeper evm.StakingKeeper,
tracer string,
) Keeper {
Expand Down
17 changes: 12 additions & 5 deletions x/evm/keeper/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ import (

var _ statedb.Keeper = &Keeper{}

func (k *Keeper) NewStateDB(
ctx sdk.Context,
txConfig statedb.TxConfig,
) *statedb.StateDB {
return statedb.New(ctx, k, txConfig)
}

// ----------------------------------------------------------------------------
// StateDB Keeper implementation
// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -73,26 +80,26 @@ func (k *Keeper) SetAccBalance(
ctx sdk.Context, addr gethcommon.Address, amountEvmDenom *big.Int,
) error {
nativeAddr := sdk.AccAddress(addr.Bytes())
balance := k.bankKeeper.BaseKeeper.GetBalance(ctx, nativeAddr, evm.EVMBankDenom).Amount.BigInt()
balance := k.bankKeeper.GetBalance(ctx, nativeAddr, evm.EVMBankDenom).Amount.BigInt()
delta := new(big.Int).Sub(amountEvmDenom, balance)

switch delta.Sign() {
case 1:
// mint
coins := sdk.NewCoins(sdk.NewCoin(evm.EVMBankDenom, sdkmath.NewIntFromBigInt(delta)))
if err := k.bankKeeper.BaseKeeper.MintCoins(ctx, evm.ModuleName, coins); err != nil {
if err := k.bankKeeper.MintCoins(ctx, evm.ModuleName, coins); err != nil {
return err
}
if err := k.bankKeeper.BaseKeeper.SendCoinsFromModuleToAccount(ctx, evm.ModuleName, nativeAddr, coins); err != nil {
if err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, evm.ModuleName, nativeAddr, coins); err != nil {
return err
}
case -1:
// burn
coins := sdk.NewCoins(sdk.NewCoin(evm.EVMBankDenom, sdkmath.NewIntFromBigInt(new(big.Int).Neg(delta))))
if err := k.bankKeeper.BaseKeeper.SendCoinsFromAccountToModule(ctx, nativeAddr, evm.ModuleName, coins); err != nil {
if err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, nativeAddr, evm.ModuleName, coins); err != nil {
return err
}
if err := k.bankKeeper.BaseKeeper.BurnCoins(ctx, evm.ModuleName, coins); err != nil {
if err := k.bankKeeper.BurnCoins(ctx, evm.ModuleName, coins); err != nil {
return err
}
default:
Expand Down
39 changes: 39 additions & 0 deletions x/evm/statedb/debug.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package statedb

// Copyright (c) 2023-2024 Nibi, Inc.

import (
"github.com/ethereum/go-ethereum/common"
)

// DebugDirtiesCount is a test helper to inspect how many entries in the journal
// are still dirty (uncommitted). After calling [StateDB.Commit], this function
// should return zero.
func (s *StateDB) DebugDirtiesCount() int {
dirtiesCount := 0
for _, dirtyCount := range s.Journal.dirties {
dirtiesCount += dirtyCount
}
return dirtiesCount
}

// DebugDirties is a test helper that returns the journal's dirty account changes map.
func (s *StateDB) DebugDirties() map[common.Address]int {
return s.Journal.dirties
}

// DebugEntries is a test helper that returns the sequence of [JournalChange]
// objects added during execution.
func (s *StateDB) DebugEntries() []JournalChange {
return s.Journal.entries
}

// DebugStateObjects is a test helper that returns returns a copy of the
// [StateDB.stateObjects] map.
func (s *StateDB) DebugStateObjects() map[common.Address]*stateObject {
copyOfMap := make(map[common.Address]*stateObject)
for key, val := range s.stateObjects {
copyOfMap[key] = val
}
return copyOfMap
}
19 changes: 0 additions & 19 deletions x/evm/statedb/journal.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,25 +93,6 @@ func (j *journal) Length() int {
return len(j.entries)
}

// DirtiesCount is a test helper to inspect how many entries in the journal are
// still dirty (uncommitted). After calling [StateDB.Commit], this function should
// return zero.
func (s *StateDB) DirtiesCount() int {
dirtiesCount := 0
for _, dirtyCount := range s.Journal.dirties {
dirtiesCount += dirtyCount
}
return dirtiesCount
}

func (s *StateDB) Dirties() map[common.Address]int {
return s.Journal.dirties
}

func (s *StateDB) Entries() []JournalChange {
return s.Journal.entries
}

// ------------------------------------------------------
// createObjectChange

Expand Down
Loading

0 comments on commit 4184906

Please sign in to comment.