Skip to content

Commit

Permalink
fix funtoken.sol precompile and test
Browse files Browse the repository at this point in the history
  • Loading branch information
Unique-Divine committed Oct 22, 2024
1 parent bd08702 commit 55f75c1
Show file tree
Hide file tree
Showing 11 changed files with 105 additions and 60 deletions.
6 changes: 6 additions & 0 deletions x/evm/evmtest/test_deps.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package evmtest

import (
"context"

sdk "github.com/cosmos/cosmos-sdk/types"

gethcommon "github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -54,3 +56,7 @@ func (deps TestDeps) StateDB() *statedb.StateDB {
func (deps *TestDeps) GethSigner() gethcore.Signer {
return gethcore.LatestSignerForChainID(deps.App.EvmKeeper.EthChainID(deps.Ctx))
}

func (deps TestDeps) GoCtx() context.Context {
return sdk.WrapSDKContext(deps.Ctx)

Check warning on line 61 in x/evm/evmtest/test_deps.go

View check run for this annotation

Codecov / codecov/patch

x/evm/evmtest/test_deps.go#L60-L61

Added lines #L60 - L61 were not covered by tests
}
86 changes: 70 additions & 16 deletions x/evm/evmtest/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ import (

srvconfig "github.com/NibiruChain/nibiru/v2/app/server/config"

"github.com/cosmos/cosmos-sdk/crypto/keyring"

"github.com/NibiruChain/nibiru/v2/x/evm"
"github.com/NibiruChain/nibiru/v2/x/evm/embeds"
"github.com/NibiruChain/nibiru/v2/x/evm/statedb"
)

type GethTxType = uint8
Expand Down Expand Up @@ -123,7 +126,9 @@ func ExecuteNibiTransfer(deps *TestDeps, t *testing.T) *evm.MsgEthereumTx {
To: &recipient,
Nonce: (*hexutil.Uint64)(&nonce),
}
ethTxMsg, err := GenerateAndSignEthTxMsg(txArgs, deps)
ethTxMsg, gethSigner, krSigner, err := GenerateEthTxMsgAndSigner(txArgs, deps, deps.Sender)
require.NoError(t, err)
err = ethTxMsg.Sign(gethSigner, krSigner)

Check warning on line 131 in x/evm/evmtest/tx.go

View check run for this annotation

Codecov / codecov/patch

x/evm/evmtest/tx.go#L129-L131

Added lines #L129 - L131 were not covered by tests
require.NoError(t, err)

resp, err := deps.App.EvmKeeper.EthereumTx(sdk.WrapSDKContext(deps.Ctx), ethTxMsg)
Expand Down Expand Up @@ -153,18 +158,20 @@ func DeployContract(
bytecodeForCall := append(contract.Bytecode, packedArgs...)

nonce := deps.StateDB().GetNonce(deps.Sender.EthAddr)
msgEthTx, err := GenerateAndSignEthTxMsg(
ethTxMsg, gethSigner, krSigner, err := GenerateEthTxMsgAndSigner(

Check warning on line 161 in x/evm/evmtest/tx.go

View check run for this annotation

Codecov / codecov/patch

x/evm/evmtest/tx.go#L161

Added line #L161 was not covered by tests
evm.JsonTxArgs{
Nonce: (*hexutil.Uint64)(&nonce),
Input: (*hexutil.Bytes)(&bytecodeForCall),
From: &deps.Sender.EthAddr,
}, deps,
}, deps, deps.Sender,

Check warning on line 166 in x/evm/evmtest/tx.go

View check run for this annotation

Codecov / codecov/patch

x/evm/evmtest/tx.go#L166

Added line #L166 was not covered by tests
)
if err != nil {
return nil, errors.Wrap(err, "failed to generate and sign eth tx msg")
} else if err := ethTxMsg.Sign(gethSigner, krSigner); err != nil {
return nil, errors.Wrap(err, "failed to generate and sign eth tx msg")

Check warning on line 171 in x/evm/evmtest/tx.go

View check run for this annotation

Codecov / codecov/patch

x/evm/evmtest/tx.go#L170-L171

Added lines #L170 - L171 were not covered by tests
}

resp, err := deps.App.EvmKeeper.EthereumTx(sdk.WrapSDKContext(deps.Ctx), msgEthTx)
resp, err := deps.App.EvmKeeper.EthereumTx(sdk.WrapSDKContext(deps.Ctx), ethTxMsg)

Check warning on line 174 in x/evm/evmtest/tx.go

View check run for this annotation

Codecov / codecov/patch

x/evm/evmtest/tx.go#L174

Added line #L174 was not covered by tests
if err != nil {
return nil, errors.Wrap(err, "failed to execute ethereum tx")
}
Expand All @@ -174,7 +181,7 @@ func DeployContract(

return &DeployContractResult{
TxResp: resp,
EthTxMsg: msgEthTx,
EthTxMsg: ethTxMsg,

Check warning on line 184 in x/evm/evmtest/tx.go

View check run for this annotation

Codecov / codecov/patch

x/evm/evmtest/tx.go#L184

Added line #L184 was not covered by tests
ContractData: contract,
Nonce: nonce,
ContractAddr: crypto.CreateAddress(deps.Sender.EthAddr, nonce),
Expand Down Expand Up @@ -210,23 +217,70 @@ func DeployAndExecuteERC20Transfer(
Nonce: (*hexutil.Uint64)(&nonce),
Data: (*hexutil.Bytes)(&input),
}
erc20Transfer, err = GenerateAndSignEthTxMsg(txArgs, deps)
erc20Transfer, gethSigner, krSigner, err := GenerateEthTxMsgAndSigner(txArgs, deps, deps.Sender)
require.NoError(t, err)
err = erc20Transfer.Sign(gethSigner, krSigner)

Check warning on line 222 in x/evm/evmtest/tx.go

View check run for this annotation

Codecov / codecov/patch

x/evm/evmtest/tx.go#L220-L222

Added lines #L220 - L222 were not covered by tests
require.NoError(t, err)

resp, err := deps.App.EvmKeeper.EthereumTx(sdk.WrapSDKContext(deps.Ctx), erc20Transfer)
resp, err := deps.App.EvmKeeper.EthereumTx(deps.GoCtx(), erc20Transfer)

Check warning on line 225 in x/evm/evmtest/tx.go

View check run for this annotation

Codecov / codecov/patch

x/evm/evmtest/tx.go#L225

Added line #L225 was not covered by tests
require.NoError(t, err)
require.Empty(t, resp.VmError)

return erc20Transfer, predecessors
}

// GenerateAndSignEthTxMsg estimates gas, sets gas limit and sings the tx
func GenerateAndSignEthTxMsg(
jsonTxArgs evm.JsonTxArgs, deps *TestDeps,
) (*evm.MsgEthereumTx, error) {
func CallContractTx(
deps *TestDeps,
contractAddr gethcommon.Address,
input []byte,
sender EthPrivKeyAcc,
) (ethTxMsg *evm.MsgEthereumTx, resp *evm.MsgEthereumTxResponse, err error) {
nonce := deps.StateDB().GetNonce(sender.EthAddr)
ethTxMsg, gethSigner, krSigner, err := GenerateEthTxMsgAndSigner(evm.JsonTxArgs{
From: &sender.EthAddr,
To: &contractAddr,
Nonce: (*hexutil.Uint64)(&nonce),
Data: (*hexutil.Bytes)(&input),
}, deps, sender)
if err != nil {
err = fmt.Errorf("CallContract error during tx generation: %w", err)
return
}

Check warning on line 248 in x/evm/evmtest/tx.go

View check run for this annotation

Codecov / codecov/patch

x/evm/evmtest/tx.go#L237-L248

Added lines #L237 - L248 were not covered by tests

txConfig := deps.EvmKeeper.TxConfig(deps.Ctx, gethcommon.HexToHash(ethTxMsg.Hash))
stateDB := statedb.New(deps.Ctx, &deps.EvmKeeper, txConfig)
err = stateDB.Commit()
if err != nil {
return
}

Check warning on line 255 in x/evm/evmtest/tx.go

View check run for this annotation

Codecov / codecov/patch

x/evm/evmtest/tx.go#L250-L255

Added lines #L250 - L255 were not covered by tests

err = ethTxMsg.Sign(gethSigner, krSigner)
if err != nil {
err = fmt.Errorf("CallContract error during signature: %w", err)
return
}

Check warning on line 261 in x/evm/evmtest/tx.go

View check run for this annotation

Codecov / codecov/patch

x/evm/evmtest/tx.go#L257-L261

Added lines #L257 - L261 were not covered by tests

resp, err = deps.EvmKeeper.EthereumTx(deps.GoCtx(), ethTxMsg)
return ethTxMsg, resp, err

Check warning on line 264 in x/evm/evmtest/tx.go

View check run for this annotation

Codecov / codecov/patch

x/evm/evmtest/tx.go#L263-L264

Added lines #L263 - L264 were not covered by tests
}

// GenerateEthTxMsgAndSigner estimates gas, sets gas limit and returns signer for
// the tx.
//
// Usage:
//
// ```go
// evmTxMsg, gethSigner, krSigner, _ := GenerateEthTxMsgAndSigner(
// jsonTxArgs, &deps, sender,
// )
// err := evmTxMsg.Sign(gethSigner, sender.KeyringSigner)
// ```
func GenerateEthTxMsgAndSigner(
jsonTxArgs evm.JsonTxArgs, deps *TestDeps, sender EthPrivKeyAcc,
) (evmTxMsg *evm.MsgEthereumTx, gethSigner gethcore.Signer, krSigner keyring.Signer, err error) {

Check warning on line 280 in x/evm/evmtest/tx.go

View check run for this annotation

Codecov / codecov/patch

x/evm/evmtest/tx.go#L280

Added line #L280 was not covered by tests
estimateArgs, err := json.Marshal(&jsonTxArgs)
if err != nil {
return nil, err
return

Check warning on line 283 in x/evm/evmtest/tx.go

View check run for this annotation

Codecov / codecov/patch

x/evm/evmtest/tx.go#L283

Added line #L283 was not covered by tests
}
res, err := deps.App.EvmKeeper.EstimateGas(
sdk.WrapSDKContext(deps.Ctx),
Expand All @@ -238,13 +292,13 @@ func GenerateAndSignEthTxMsg(
},
)
if err != nil {
return nil, err
return

Check warning on line 295 in x/evm/evmtest/tx.go

View check run for this annotation

Codecov / codecov/patch

x/evm/evmtest/tx.go#L295

Added line #L295 was not covered by tests
}
jsonTxArgs.Gas = (*hexutil.Uint64)(&res.Gas)

msgEthTx := jsonTxArgs.ToMsgEthTx()
gethSigner := gethcore.LatestSignerForChainID(deps.App.EvmKeeper.EthChainID(deps.Ctx))
return msgEthTx, msgEthTx.Sign(gethSigner, deps.Sender.KeyringSigner)
evmTxMsg = jsonTxArgs.ToMsgEthTx()
gethSigner = gethcore.LatestSignerForChainID(deps.App.EvmKeeper.EthChainID(deps.Ctx))
return evmTxMsg, gethSigner, sender.KeyringSigner, nil

Check warning on line 301 in x/evm/evmtest/tx.go

View check run for this annotation

Codecov / codecov/patch

x/evm/evmtest/tx.go#L299-L301

Added lines #L299 - L301 were not covered by tests
}

func TransferWei(
Expand Down
5 changes: 2 additions & 3 deletions x/evm/keeper/erc20.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,9 @@ func (k Keeper) CallContractWithInput(
}

blockHash := gethcommon.BytesToHash(ctx.HeaderHash())
// txIdx := uint(k.EvmState.BlockTxIndex.GetOr(ctx, 0)) // TxIndex
// txLogIdx := uint(k.EvmState.BlockLogSize.GetOr(ctx, 0)) // LogIndex
ctx.TxBytes()
txConfig := statedb.NewEmptyTxConfig(blockHash)
txConfig.TxIndex = uint(k.EvmState.BlockLogSize.GetOr(ctx, 0))
txConfig.LogIndex = uint(k.EvmState.BlockLogSize.GetOr(ctx, 0))

evmResp, err = k.ApplyEvmMsg(
ctx, evmMsg, evm.NewNoOpTracer(), commit, evmCfg, txConfig,
Expand Down
2 changes: 1 addition & 1 deletion x/evm/keeper/funtoken_from_coin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ func (s *FunTokenFromCoinSuite) TestConvertCoinToEvmAndBack() {
// Check 3: erc-20 balance
balance, err = deps.EvmKeeper.ERC20().BalanceOf(funTokenErc20Addr.Address, alice.EthAddr, deps.Ctx)
s.Require().NoError(err)
s.Require().Zero(balance.Cmp(big.NewInt(0)))
s.Require().Equal("0", balance.String())

s.T().Log("sad: Convert more erc-20 to back to bank coin, insufficient funds")
_, err = deps.EvmKeeper.CallContract(
Expand Down
15 changes: 8 additions & 7 deletions x/evm/keeper/funtoken_from_erc20_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ func (s *FunTokenFromErc20Suite) TestCreateFunTokenFromERC20() {
s.ErrorContains(err, "either the \"from_erc20\" or \"from_bank_denom\" must be set")
}

func (s *FunTokenFromErc20Suite) TestSendFromEvmToCosmos() {
func (s *FunTokenFromErc20Suite) TestSendFromEvmToBank() {
deps := evmtest.NewTestDeps()

s.T().Log("Deploy ERC20")
Expand Down Expand Up @@ -210,7 +210,7 @@ func (s *FunTokenFromErc20Suite) TestSendFromEvmToCosmos() {

randomAcc := testutil.AccAddress()

s.T().Log("send erc20 tokens to cosmos")
s.T().Log("send erc20 tokens to Bank")
_, err = deps.EvmKeeper.CallContract(
deps.Ctx,
embeds.SmartContract_FunToken.ABI,
Expand All @@ -231,8 +231,8 @@ func (s *FunTokenFromErc20Suite) TestSendFromEvmToCosmos() {
deps.App.BankKeeper.GetBalance(deps.Ctx, randomAcc, bankDemon).Amount,
)

s.T().Log("sad: send too many erc20 tokens to cosmos")
_, err = deps.EvmKeeper.CallContract(
s.T().Log("sad: send too many erc20 tokens to Bank")
evmResp, err := deps.EvmKeeper.CallContract(
deps.Ctx,
embeds.SmartContract_FunToken.ABI,
deps.Sender.EthAddr,
Expand All @@ -243,9 +243,10 @@ func (s *FunTokenFromErc20Suite) TestSendFromEvmToCosmos() {
big.NewInt(70_000),
randomAcc.String(),
)
s.Require().Error(err)
s.T().Log("check balances")
s.Require().Error(err, evmResp.String())

s.T().Log("send cosmos tokens back to erc20")
s.T().Log("send Bank tokens back to erc20")
_, err = deps.EvmKeeper.ConvertCoinToEvm(sdk.WrapSDKContext(deps.Ctx),
&evm.MsgConvertCoinToEvm{
ToEthAddr: eth.EIP55Addr{
Expand All @@ -264,7 +265,7 @@ func (s *FunTokenFromErc20Suite) TestSendFromEvmToCosmos() {
deps.App.BankKeeper.GetBalance(deps.Ctx, randomAcc, bankDemon).Amount.Equal(sdk.NewInt(0)),
)

s.T().Log("sad: send too many cosmos tokens back to erc20")
s.T().Log("sad: send too many Bank tokens back to erc20")
_, err = deps.EvmKeeper.ConvertCoinToEvm(sdk.WrapSDKContext(deps.Ctx),
&evm.MsgConvertCoinToEvm{
ToEthAddr: eth.EIP55Addr{
Expand Down
24 changes: 0 additions & 24 deletions x/evm/precompile/abci_event.go

This file was deleted.

5 changes: 4 additions & 1 deletion x/evm/precompile/funtoken.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func (p precompileFunToken) Run(
evm *vm.EVM, contract *vm.Contract, readonly bool,
) (bz []byte, err error) {
defer ErrPrecompileRun(err, p)()

res, err := OnRunStart(evm, contract, embeds.SmartContract_FunToken.ABI)
if err != nil {
return nil, err
Expand All @@ -61,7 +62,9 @@ func (p precompileFunToken) Run(
err = fmt.Errorf("invalid method called with name \"%s\"", method.Name)
return
}

if err != nil {
return nil, err
}

Check warning on line 67 in x/evm/precompile/funtoken.go

View check run for this annotation

Codecov / codecov/patch

x/evm/precompile/funtoken.go#L66-L67

Added lines #L66 - L67 were not covered by tests
if err := OnRunEnd(res.StateDB, res.SnapshotBeforeRun, p.Address()); err != nil {
return nil, err
}

Check warning on line 70 in x/evm/precompile/funtoken.go

View check run for this annotation

Codecov / codecov/patch

x/evm/precompile/funtoken.go#L69-L70

Added lines #L69 - L70 were not covered by tests
Expand Down
16 changes: 10 additions & 6 deletions x/evm/precompile/funtoken_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"
gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/suite"

"github.com/NibiruChain/nibiru/v2/eth"
Expand Down Expand Up @@ -49,19 +49,19 @@ func (s *FuntokenSuite) TestFailToPackABI() {
{
name: "wrong type for amount",
methodName: string(precompile.FunTokenMethod_BankSend),
callArgs: []any{common.HexToAddress("0x7D4B7B8CA7E1a24928Bb96D59249c7a5bd1DfBe6"), "foo", testutil.AccAddress().String()},
callArgs: []any{gethcommon.HexToAddress("0x7D4B7B8CA7E1a24928Bb96D59249c7a5bd1DfBe6"), "foo", testutil.AccAddress().String()},
wantError: "abi: cannot use string as type ptr as argument",
},
{
name: "wrong type for recipient",
methodName: string(precompile.FunTokenMethod_BankSend),
callArgs: []any{common.HexToAddress("0x7D4B7B8CA7E1a24928Bb96D59249c7a5bd1DfBe6"), big.NewInt(1), 111},
callArgs: []any{gethcommon.HexToAddress("0x7D4B7B8CA7E1a24928Bb96D59249c7a5bd1DfBe6"), big.NewInt(1), 111},
wantError: "abi: cannot use int as type string as argument",
},
{
name: "invalid method name",
methodName: "foo",
callArgs: []any{common.HexToAddress("0x7D4B7B8CA7E1a24928Bb96D59249c7a5bd1DfBe6"), big.NewInt(1), testutil.AccAddress().String()},
callArgs: []any{gethcommon.HexToAddress("0x7D4B7B8CA7E1a24928Bb96D59249c7a5bd1DfBe6"), big.NewInt(1), testutil.AccAddress().String()},
wantError: "method 'foo' not found",
},
}
Expand Down Expand Up @@ -126,10 +126,14 @@ func (s *FuntokenSuite) TestHappyPath() {
input, err := embeds.SmartContract_FunToken.ABI.Pack(string(precompile.FunTokenMethod_BankSend), callArgs...)
s.NoError(err)

_, err = deps.EvmKeeper.CallContractWithInput(
deps.Ctx, deps.Sender.EthAddr, &precompile.PrecompileAddr_FunToken, true, input,
_, resp, err := evmtest.CallContractTx(
&deps,
precompile.PrecompileAddr_FunToken,
input,
deps.Sender,
)
s.Require().NoError(err)
s.Require().Empty(resp.VmError)

evmtest.AssertERC20BalanceEqual(s.T(), deps, erc20, deps.Sender.EthAddr, big.NewInt(69_000))
evmtest.AssertERC20BalanceEqual(s.T(), deps, erc20, evm.EVM_MODULE_ADDRESS, big.NewInt(0))
Expand Down
3 changes: 3 additions & 0 deletions x/evm/precompile/wasm.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ func (p precompileWasm) Run(
err = fmt.Errorf("invalid method called with name \"%s\"", method.Name)
return
}
if err != nil {
return nil, err
}

if err := OnRunEnd(res.StateDB, res.SnapshotBeforeRun, p.Address()); err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion x/evm/statedb/journal.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ func (ch PrecompileSnapshotBeforeRun) Revert(s *StateDB) {
// TODO: Revert PrecompileSnapshotBeforeRun
// Restore the multistore recorded in the journal entry

fmt.Printf("\"Revert was called.\"\n")
fmt.Printf("TODO: UD-DEBUG: PrecompileSnapshotBeforeRun.Revert called\n")

s.cacheCtx = s.cacheCtx.WithMultiStore(ch.MultiStore)
// Rewrite the `writeCacheCtxFn` using the same logic as sdk.Context.CacheCtx
Expand Down
1 change: 0 additions & 1 deletion x/evm/statedb/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,6 @@ func (s *StateDB) SavePrecompileSnapshotToJournal(
precompileAddr common.Address,
snapshot PrecompileSnapshotBeforeRun,
) error {
fmt.Println("SavePrecompileSnapshotToJournal was called")
obj := s.getOrNewStateObject(precompileAddr)
obj.db.journal.append(snapshot)
s.precompileSnapshotsCount++
Expand Down

0 comments on commit 55f75c1

Please sign in to comment.