diff --git a/.github/workflows/compatiblity_check.yml b/.github/workflows/compatiblity_check.yml index d76d5d7462..bffb0ad219 100644 --- a/.github/workflows/compatiblity_check.yml +++ b/.github/workflows/compatiblity_check.yml @@ -17,8 +17,8 @@ jobs: - name: Check Latest Dependencies run: | - git clone https://github.com/sei-protocol/sei-cosmos.git - git clone https://github.com/sei-protocol/sei-tendermint.git + git clone -b evm-temp https://github.com/sei-protocol/sei-cosmos.git + git clone -b evm-temp https://github.com/sei-protocol/sei-tendermint.git git clone https://github.com/sei-protocol/sei-iavl.git git clone https://github.com/sei-protocol/go-ethereum.git go mod edit -replace github.com/cosmos/iavl=./sei-iavl diff --git a/aclmapping/evm/mappings.go b/aclmapping/evm/mappings.go index 39c2e4c5d2..d29d329490 100644 --- a/aclmapping/evm/mappings.go +++ b/aclmapping/evm/mappings.go @@ -47,6 +47,13 @@ func TransactionDependencyGenerator(_ aclkeeper.Keeper, evmKeeper evmkeeper.Keep ops = appendRWBalanceOps(ops, state.GetCoinbaseAddress(ctx)) sender := sdk.AccAddress(evmMsg.Derived.SenderSeiAddr) ops = appendRWBalanceOps(ops, sender) + ops = append(ops, + sdkacltypes.AccessOperation{ + AccessType: sdkacltypes.AccessType_READ, + ResourceType: sdkacltypes.ResourceType_KV_BANK_WEI_BALANCE, + IdentifierTemplate: hex.EncodeToString(append(banktypes.WeiBalancesPrefix, sender...)), + }, + ) tx, _ := evmMsg.AsTransaction() toAddress := tx.To() diff --git a/aclmapping/evm/mappings_test.go b/aclmapping/evm/mappings_test.go index 1bf78a864e..9f4a664130 100644 --- a/aclmapping/evm/mappings_test.go +++ b/aclmapping/evm/mappings_test.go @@ -75,8 +75,8 @@ func cacheTxContext(ctx sdk.Context) (sdk.Context, sdk.CacheMultiStore) { func (suite *KeeperTestSuite) buildSendMsgTo(to common.Address, amt *big.Int) *types.MsgEVMTransaction { txData := ethtypes.DynamicFeeTx{ Nonce: 0, - GasFeeCap: big.NewInt(1), - Gas: 21000, + GasFeeCap: big.NewInt(1000000000), + Gas: 30000, To: &to, Value: amt, Data: []byte(""), diff --git a/aclmapping/utils/resource_type.go b/aclmapping/utils/resource_type.go index 39dcf3411a..2528000ad6 100644 --- a/aclmapping/utils/resource_type.go +++ b/aclmapping/utils/resource_type.go @@ -62,10 +62,11 @@ var StoreKeyToResourceTypePrefixMap = aclsdktypes.StoreKeyToResourceTypePrefixMa aclsdktypes.ResourceType_KV_DEX_MEM_DEPOSIT: dextypes.KeyPrefix(dextypes.MemDepositKey), }, banktypes.StoreKey: { - aclsdktypes.ResourceType_KV_BANK: aclsdktypes.EmptyPrefix, - aclsdktypes.ResourceType_KV_BANK_BALANCES: banktypes.BalancesPrefix, - aclsdktypes.ResourceType_KV_BANK_SUPPLY: banktypes.SupplyKey, - aclsdktypes.ResourceType_KV_BANK_DENOM: banktypes.DenomMetadataPrefix, + aclsdktypes.ResourceType_KV_BANK: aclsdktypes.EmptyPrefix, + aclsdktypes.ResourceType_KV_BANK_BALANCES: banktypes.BalancesPrefix, + aclsdktypes.ResourceType_KV_BANK_SUPPLY: banktypes.SupplyKey, + aclsdktypes.ResourceType_KV_BANK_DENOM: banktypes.DenomMetadataPrefix, + aclsdktypes.ResourceType_KV_BANK_WEI_BALANCE: banktypes.WeiBalancesPrefix, }, banktypes.DeferredCacheStoreKey: { aclsdktypes.ResourceType_KV_BANK_DEFERRED: aclsdktypes.EmptyPrefix, diff --git a/app/app.go b/app/app.go index da1158f020..647d9f4a8a 100644 --- a/app/app.go +++ b/app/app.go @@ -223,6 +223,7 @@ var ( evmtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, dexmoduletypes.ModuleName: nil, tokenfactorytypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + banktypes.WeiEscrowName: nil, // this line is used by starport scaffolding # stargate/app/maccPerms } diff --git a/go.mod b/go.mod index 022ea52855..97bfbc2645 100644 --- a/go.mod +++ b/go.mod @@ -322,7 +322,7 @@ require ( replace ( github.com/CosmWasm/wasmd => github.com/sei-protocol/sei-wasmd v0.0.2 github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 - github.com/cosmos/cosmos-sdk => github.com/sei-protocol/sei-cosmos v0.2.66-evm-11 + github.com/cosmos/cosmos-sdk => github.com/sei-protocol/sei-cosmos v0.2.66-evm-13 github.com/cosmos/iavl => github.com/sei-protocol/sei-iavl v0.1.7 github.com/cosmos/ibc-go/v3 => github.com/sei-protocol/sei-ibc-go/v3 v3.2.0 github.com/ethereum/go-ethereum => github.com/sei-protocol/go-ethereum v1.13.5-sei diff --git a/go.sum b/go.sum index a34e06e708..799f18164e 100644 --- a/go.sum +++ b/go.sum @@ -1325,8 +1325,8 @@ github.com/sei-protocol/go-ethereum v1.13.5-sei h1:050SdAmqc3JWULg69daOXaVRvowwp github.com/sei-protocol/go-ethereum v1.13.5-sei/go.mod h1:kcRZmuzRn1lVejiFNTz4l4W7imnpq1bDAnuKS/RyhbQ= github.com/sei-protocol/goutils v0.0.2 h1:Bfa7Sv+4CVLNM20QcpvGb81B8C5HkQC/kW1CQpIbXDA= github.com/sei-protocol/goutils v0.0.2/go.mod h1:iYE2DuJfEnM+APPehr2gOUXfuLuPsVxorcDO+Tzq9q8= -github.com/sei-protocol/sei-cosmos v0.2.66-evm-11 h1:IZUtYzhdFbMaE9H4VGQBjcYEQSrARGfeizDp0wvCECw= -github.com/sei-protocol/sei-cosmos v0.2.66-evm-11/go.mod h1:FrJ75cMf1+Mx/AVWGzpcrCtvBoXd1wurJSRHCtP0cvQ= +github.com/sei-protocol/sei-cosmos v0.2.66-evm-13 h1:BK9WSVu66oY8p8Cx8EbwvDJO0G/MQPq35gI5rc1lcmY= +github.com/sei-protocol/sei-cosmos v0.2.66-evm-13/go.mod h1:FrJ75cMf1+Mx/AVWGzpcrCtvBoXd1wurJSRHCtP0cvQ= github.com/sei-protocol/sei-iavl v0.1.7 h1:cUdHDBkxs0FF/kOt1qCVLm0K+Bqaw92/dbZSgn4kxiA= github.com/sei-protocol/sei-iavl v0.1.7/go.mod h1:7PfkEVT5dcoQE+s/9KWdoXJ8VVVP1QpYYPLdxlkSXFk= github.com/sei-protocol/sei-ibc-go/v3 v3.2.0 h1:T8V75OEWKvYDraPZZKilprl7ZkahZYGo40crxNL4unc= diff --git a/x/evm/client/cli/tx.go b/x/evm/client/cli/tx.go index 922d422070..9b45baa39e 100644 --- a/x/evm/client/cli/tx.go +++ b/x/evm/client/cli/tx.go @@ -27,7 +27,6 @@ import ( ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/sei-protocol/sei-chain/evmrpc" "github.com/sei-protocol/sei-chain/x/evm/artifacts" - "github.com/sei-protocol/sei-chain/x/evm/state" "github.com/sei-protocol/sei-chain/x/evm/types" "github.com/sei-protocol/sei-chain/x/evm/types/ethtx" ) @@ -138,7 +137,7 @@ func CmdAssociateAddress() *cobra.Command { func CmdSend() *cobra.Command { cmd := &cobra.Command{ - Use: "send [to EVM address] [amount in usei] --from= --gas-fee-cap= --gas-limit= --evm-chain-id= --evm-rpc=", + Use: "send [to EVM address] [amount in wei] --from= --gas-fee-cap= --gas-limit= --evm-chain-id= --evm-rpc=", Short: "send usei to EVM address", Long: "", Args: cobra.ExactArgs(2), @@ -193,9 +192,9 @@ func CmdSend() *cobra.Command { } to := common.HexToAddress(args[0]) - val, err := strconv.ParseUint(args[1], 10, 64) - if err != nil { - return err + val, success := new(big.Int).SetString(args[1], 10) + if !success { + return fmt.Errorf("%s is an invalid amount to send", args[1]) } gasFeeCap, err := cmd.Flags().GetUint64(FlagGasFeeCap) if err != nil { @@ -214,7 +213,7 @@ func CmdSend() *cobra.Command { GasFeeCap: new(big.Int).SetUint64(gasFeeCap), Gas: gasLimit, To: &to, - Value: new(big.Int).Mul(new(big.Int).SetUint64(val), state.UseiToSweiMultiplier), + Value: val, Data: []byte(""), ChainID: new(big.Int).SetUint64(chainID), } diff --git a/x/evm/module.go b/x/evm/module.go index e556cebcac..d7db91beb0 100644 --- a/x/evm/module.go +++ b/x/evm/module.go @@ -159,18 +159,21 @@ func (am AppModule) BeginBlock(sdk.Context, abci.RequestBeginBlock) { // returns no validator updates. func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { evmTxIndices := am.keeper.GetEVMTxIndices() + denom := am.keeper.GetBaseDenom(ctx) for _, idx := range evmTxIndices { middleManAddress := state.GetMiddleManAddress(sdk.Context{}.WithTxIndex(idx)) - balances := am.keeper.BankKeeper().GetAllBalances(ctx, middleManAddress) - if !balances.IsZero() { - if err := am.keeper.BankKeeper().SendCoinsFromAccountToModule(ctx, middleManAddress, types.ModuleName, balances); err != nil { + balance := am.keeper.BankKeeper().GetBalance(ctx, middleManAddress, denom) + weiBalance := am.keeper.BankKeeper().GetWeiBalance(ctx, middleManAddress) + if !balance.Amount.IsZero() || !weiBalance.IsZero() { + if err := am.keeper.BankKeeper().SendCoinsAndWei(ctx, middleManAddress, am.keeper.AccountKeeper().GetModuleAddress(types.ModuleName), nil, denom, balance.Amount, weiBalance); err != nil { panic(err) } } coinbaseAddress := state.GetCoinbaseAddress(sdk.Context{}.WithTxIndex(idx)) - balances = am.keeper.BankKeeper().GetAllBalances(ctx, coinbaseAddress) - if !balances.IsZero() { - if err := am.keeper.BankKeeper().SendCoinsFromAccountToModule(ctx, coinbaseAddress, authtypes.FeeCollectorName, balances); err != nil { + balance = am.keeper.BankKeeper().GetBalance(ctx, coinbaseAddress, denom) + weiBalance = am.keeper.BankKeeper().GetWeiBalance(ctx, coinbaseAddress) + if !balance.Amount.IsZero() || !weiBalance.IsZero() { + if err := am.keeper.BankKeeper().SendCoinsAndWei(ctx, coinbaseAddress, am.keeper.AccountKeeper().GetModuleAddress(authtypes.FeeCollectorName), nil, denom, balance.Amount, weiBalance); err != nil { panic(err) } } diff --git a/x/evm/state/balance.go b/x/evm/state/balance.go index 77d79b8556..46774540bb 100644 --- a/x/evm/state/balance.go +++ b/x/evm/state/balance.go @@ -17,7 +17,7 @@ func (s *DBImpl) SubBalance(evmAddr common.Address, amt *big.Int) { return } - s.err = s.k.BankKeeper().SendCoinsWithoutAccCreation(s.ctx, s.getSeiAddress(evmAddr), s.middleManAddress, s.bigIntAmtToCoins(amt)) + s.send(s.getSeiAddress(evmAddr), s.middleManAddress, amt) } func (s *DBImpl) AddBalance(evmAddr common.Address, amt *big.Int) { @@ -29,11 +29,13 @@ func (s *DBImpl) AddBalance(evmAddr common.Address, amt *big.Int) { return } - s.err = s.k.BankKeeper().SendCoinsWithoutAccCreation(s.ctx, s.middleManAddress, s.getSeiAddress(evmAddr), s.bigIntAmtToCoins(amt)) + s.send(s.middleManAddress, s.getSeiAddress(evmAddr), amt) } func (s *DBImpl) GetBalance(evmAddr common.Address) *big.Int { - return s.coinToBigIntAmt(s.k.BankKeeper().GetBalance(s.ctx, s.getSeiAddress(evmAddr), s.k.GetBaseDenom(s.ctx))) + usei := s.k.BankKeeper().GetBalance(s.ctx, s.getSeiAddress(evmAddr), s.k.GetBaseDenom(s.ctx)).Amount + wei := s.k.BankKeeper().GetWeiBalance(s.ctx, s.getSeiAddress(evmAddr)) + return usei.Mul(sdk.NewIntFromBigInt(UseiToSweiMultiplier)).Add(wei).BigInt() } // should only be called during simulation @@ -41,20 +43,20 @@ func (s *DBImpl) SetBalance(evmAddr common.Address, amt *big.Int) { if !s.simulation { panic("should never call SetBalance in a non-simulation setting") } - // Fields that were denominated in usei will be converted to swei (1usei = 10^12swei) - // for existing Ethereum application (which assumes 18 decimal points) to display properly. - amt = new(big.Int).Quo(amt, UseiToSweiMultiplier) seiAddr := s.getSeiAddress(evmAddr) - balance := s.k.BankKeeper().GetBalance(s.ctx, seiAddr, s.k.GetBaseDenom(s.ctx)) - if err := s.k.BankKeeper().SendCoinsFromAccountToModule(s.ctx, seiAddr, types.ModuleName, sdk.NewCoins(balance)); err != nil { - panic(err) + moduleAddr := s.k.AccountKeeper().GetModuleAddress(types.ModuleName) + s.send(seiAddr, moduleAddr, s.GetBalance(evmAddr)) + if s.err != nil { + panic(s.err) } - coinsAmt := sdk.NewCoins(sdk.NewCoin(s.k.GetBaseDenom(s.ctx), sdk.NewIntFromBigInt(amt))) + usei, _ := SplitUseiWeiAmount(amt) + coinsAmt := sdk.NewCoins(sdk.NewCoin(s.k.GetBaseDenom(s.ctx), sdk.NewIntFromBigInt(usei).Add(sdk.OneInt()))) if err := s.k.BankKeeper().MintCoins(s.ctx, types.ModuleName, coinsAmt); err != nil { panic(err) } - if err := s.k.BankKeeper().SendCoinsFromModuleToAccount(s.ctx, types.ModuleName, seiAddr, coinsAmt); err != nil { - panic(err) + s.send(moduleAddr, seiAddr, amt) + if s.err != nil { + panic(s.err) } } @@ -69,14 +71,7 @@ func (s *DBImpl) getSeiAddress(evmAddr common.Address) (seiAddr sdk.AccAddress) return } -func (s *DBImpl) bigIntAmtToCoins(amt *big.Int) sdk.Coins { - // Fields that were denominated in usei will be converted to swei (1usei = 10^12swei) - // for existing Ethereum application (which assumes 18 decimal points) to display properly. - amt = new(big.Int).Quo(amt, UseiToSweiMultiplier) - return sdk.NewCoins(sdk.NewCoin(s.k.GetBaseDenom(s.ctx), sdk.NewIntFromBigInt(amt))) -} - -func (s *DBImpl) coinToBigIntAmt(coin sdk.Coin) *big.Int { - balanceInUsei := coin.Amount.BigInt() - return new(big.Int).Mul(balanceInUsei, UseiToSweiMultiplier) +func (s *DBImpl) send(from sdk.AccAddress, to sdk.AccAddress, amt *big.Int) { + usei, wei := SplitUseiWeiAmount(amt) + s.err = s.k.BankKeeper().SendCoinsAndWei(s.ctx, from, to, nil, s.k.GetBaseDenom(s.ctx), sdk.NewIntFromBigInt(usei), sdk.NewIntFromBigInt(wei)) } diff --git a/x/evm/state/statedb.go b/x/evm/state/statedb.go index 7d53d74982..14c6deaa05 100644 --- a/x/evm/state/statedb.go +++ b/x/evm/state/statedb.go @@ -109,10 +109,13 @@ func (s *DBImpl) GetStorageRoot(common.Address) common.Hash { func (s *DBImpl) Copy() vm.StateDB { newCtx := s.ctx.WithMultiStore(s.ctx.MultiStore().CacheMultiStore()) return &DBImpl{ - ctx: newCtx, - snapshottedCtxs: append(s.snapshottedCtxs, s.ctx), - k: s.k, - err: s.err, + ctx: newCtx, + snapshottedCtxs: append(s.snapshottedCtxs, s.ctx), + k: s.k, + middleManAddress: s.middleManAddress, + coinbaseAddress: s.coinbaseAddress, + simulation: s.simulation, + err: s.err, } } diff --git a/x/evm/state/utils.go b/x/evm/state/utils.go index 1288c4bd10..7801fe5a4b 100644 --- a/x/evm/state/utils.go +++ b/x/evm/state/utils.go @@ -25,3 +25,9 @@ func GetCoinbaseAddress(ctx sdk.Context) sdk.AccAddress { binary.BigEndian.PutUint64(txIndexBz, uint64(ctx.TxIndex())) return sdk.AccAddress(append(CoinbaseAddressPrefix, txIndexBz...)) } + +func SplitUseiWeiAmount(amt *big.Int) (usei *big.Int, wei *big.Int) { + wei = new(big.Int).Mod(amt, UseiToSweiMultiplier) + usei = new(big.Int).Quo(amt, UseiToSweiMultiplier) + return +} diff --git a/x/evm/state/utils_test.go b/x/evm/state/utils_test.go new file mode 100644 index 0000000000..c482e38b76 --- /dev/null +++ b/x/evm/state/utils_test.go @@ -0,0 +1,47 @@ +package state_test + +import ( + "math/big" + "testing" + + "github.com/sei-protocol/sei-chain/x/evm/state" + "github.com/stretchr/testify/require" +) + +func TestSplitUseiWeiAmount(t *testing.T) { + for _, test := range []struct { + amt *big.Int + expectedSei *big.Int + expectedWei *big.Int + }{ + { + amt: big.NewInt(0), + expectedSei: big.NewInt(0), + expectedWei: big.NewInt(0), + }, { + amt: big.NewInt(1), + expectedSei: big.NewInt(0), + expectedWei: big.NewInt(1), + }, { + amt: big.NewInt(999_999_999_999), + expectedSei: big.NewInt(0), + expectedWei: big.NewInt(999_999_999_999), + }, { + amt: big.NewInt(1_000_000_000_000), + expectedSei: big.NewInt(1), + expectedWei: big.NewInt(0), + }, { + amt: big.NewInt(1_000_000_000_001), + expectedSei: big.NewInt(1), + expectedWei: big.NewInt(1), + }, { + amt: big.NewInt(123_456_789_123_456_789), + expectedSei: big.NewInt(123456), + expectedWei: big.NewInt(789_123_456_789), + }, + } { + usei, wei := state.SplitUseiWeiAmount(test.amt) + require.Equal(t, test.expectedSei, usei) + require.Equal(t, test.expectedWei, wei) + } +}