Skip to content

Commit

Permalink
test: Add CREATE and basic transfer test
Browse files Browse the repository at this point in the history
  • Loading branch information
drklee3 committed Feb 28, 2024
1 parent 7b89733 commit 9957478
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 14 deletions.
12 changes: 12 additions & 0 deletions contract/contracts/EIP161Test.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,16 @@ contract EIP161Test {

return data;
}

function createContract() public payable returns (address) {
address newContract;
bytes memory bytecode = hex"3859818153F3";
assembly {
newContract := create(0, add(bytecode, 0x20), mload(bytecode))
if iszero(extcodesize(newContract)) {
revert(0, 0)
}
}
return newContract;
}
}
75 changes: 63 additions & 12 deletions x/evm/keeper/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,15 @@ func (suite *IntegrationTestSuite) TestEIP161_TouchEmptyDeletes() {
var contractAddr common.Address
targetAddr := common.Address{10}

type accountState struct {
contractDeleted bool
targetDeleted bool
}

tests := []struct {
name string
malleate func()
wantContractDeleted bool
wantAccountDeleted bool
name string
malleate func()
wantAccountState accountState
}{
{
"not touched",
Expand All @@ -153,8 +157,10 @@ func (suite *IntegrationTestSuite) TestEIP161_TouchEmptyDeletes() {
suite.Require().NoError(err)
suite.Require().Empty(rsp.VmError)
},
true,
false,
accountState{
contractDeleted: true,
targetDeleted: false,
},
},
{
"self destruct target - 0 value",
Expand All @@ -170,8 +176,10 @@ func (suite *IntegrationTestSuite) TestEIP161_TouchEmptyDeletes() {
suite.Require().NoError(err)
suite.Require().Empty(rsp.VmError)
},
true,
true,
accountState{
contractDeleted: true,
targetDeleted: true,
},
},
{
"call target - 0 value",
Expand All @@ -187,8 +195,51 @@ func (suite *IntegrationTestSuite) TestEIP161_TouchEmptyDeletes() {
suite.Require().NoError(err)
suite.Require().Empty(rsp.VmError)
},
false,
true,
accountState{
contractDeleted: false,
targetDeleted: true,
},
},
{
"create call",
func() {
// target account with 0 value should be touched
_, rsp, err := suite.CallContract(
testutil.EIP161TestContract,
contractAddr,
common.Big0,
"createContract",
)
suite.Require().NoError(err)
suite.Require().Empty(rsp.VmError)
suite.Require().NotEmpty(rsp.Ret)

// Get the address of the created contract
contractAddr = common.BytesToAddress(rsp.Ret)
contractAcc := suite.App.EvmKeeper.GetAccount(suite.Ctx, contractAddr)
suite.Require().NotNil(contractAcc)
},
accountState{
contractDeleted: false,
targetDeleted: false,
},
},
{
"transfer zero amount",
func() {
// native transfer of 0 value funds
_, rsp, err := suite.TransferValue(
suite.Address,
targetAddr,
common.Big0,
)
suite.Require().NoError(err)
suite.Require().Empty(rsp.VmError)
},
accountState{
contractDeleted: false,
targetDeleted: true,
},
},
}

Expand All @@ -212,7 +263,7 @@ func (suite *IntegrationTestSuite) TestEIP161_TouchEmptyDeletes() {

// Check result
targetAcc = suite.App.EvmKeeper.GetAccount(suite.Ctx, targetAddr)
if tt.wantAccountDeleted {
if tt.wantAccountState.targetDeleted {
suite.Require().Nil(
targetAcc,
"EIP-161: empty account should be deleted after being touched",
Expand All @@ -225,7 +276,7 @@ func (suite *IntegrationTestSuite) TestEIP161_TouchEmptyDeletes() {
}

contractAcc := suite.App.EvmKeeper.GetAccount(suite.Ctx, contractAddr)
if tt.wantContractDeleted {
if tt.wantAccountState.contractDeleted {
suite.Require().Nil(
contractAcc,
"EIP-161: contract should be deleted after touching empty account",
Expand Down
1 change: 1 addition & 0 deletions x/evm/statedb/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ func (s *StateDB) ForEachStorage(addr common.Address, cb func(key, value common.

// AddBalance adds amount to the account associated with addr.
func (s *StateDB) AddBalance(addr common.Address, amount *big.Int) {
// Zero values still touch the account
s.TouchAccount(addr)

// Only allow positive amounts.
Expand Down
4 changes: 2 additions & 2 deletions x/evm/testutil/EIP161Test.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"abi": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"callAccount\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"selfDestructTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}]",
"bin": "608060405234801561001057600080fd5b506103ae806100206000396000f3fe6080604052600436106100295760003560e01c80636f43e2db1461002e578063a28bf7cc1461005e575b600080fd5b610048600480360381019061004391906101b0565b61007a565b604051610055919061026d565b60405180910390f35b610078600480360381019061007391906101b0565b610134565b005b60606000808373ffffffffffffffffffffffffffffffffffffffff16346040516100a3906102c0565b60006040518083038185875af1925050503d80600081146100e0576040519150601f19603f3d011682016040523d82523d6000602084013e6100e5565b606091505b50915091508161012a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012190610358565b60405180910390fd5b8092505050919050565b8073ffffffffffffffffffffffffffffffffffffffff16ff5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061017d82610152565b9050919050565b61018d81610172565b811461019857600080fd5b50565b6000813590506101aa81610184565b92915050565b6000602082840312156101c6576101c561014d565b5b60006101d48482850161019b565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156102175780820151818401526020810190506101fc565b60008484015250505050565b6000601f19601f8301169050919050565b600061023f826101dd565b61024981856101e8565b93506102598185602086016101f9565b61026281610223565b840191505092915050565b600060208201905081810360008301526102878184610234565b905092915050565b600081905092915050565b50565b60006102aa60008361028f565b91506102b58261029a565b600082019050919050565b60006102cb8261029d565b9150819050919050565b600082825260208201905092915050565b7f4661696c656420746f2063616c6c20656d707479206163636f756e742077697460008201527f682076616c756500000000000000000000000000000000000000000000000000602082015250565b60006103426027836102d5565b915061034d826102e6565b604082019050919050565b6000602082019050818103600083015261037181610335565b905091905056fea26469706673582212202a7ff12686e1e561ab3024f725bae2847933ad8957693f8abe9cacfef441546a64736f6c63430008180033"
"abi": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"callAccount\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"selfDestructTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}]",
"bin": "608060405234801561001057600080fd5b5061045c806100206000396000f3fe6080604052600436106100345760003560e01c8063412a5a6d146100395780636f43e2db14610057578063a28bf7cc14610087575b600080fd5b6100416100a3565b60405161004e9190610212565b60405180910390f35b610071600480360381019061006c919061025e565b6100fe565b60405161007e919061031b565b60405180910390f35b6100a1600480360381019061009c919061025e565b6101b8565b005b60008060006040518060400160405280600681526020017f3859818153f3000000000000000000000000000000000000000000000000000081525090508051602082016000f09150813b6100f657600080fd5b819250505090565b60606000808373ffffffffffffffffffffffffffffffffffffffff16346040516101279061036e565b60006040518083038185875af1925050503d8060008114610164576040519150601f19603f3d011682016040523d82523d6000602084013e610169565b606091505b5091509150816101ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a590610406565b60405180910390fd5b8092505050919050565b8073ffffffffffffffffffffffffffffffffffffffff16ff5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101fc826101d1565b9050919050565b61020c816101f1565b82525050565b60006020820190506102276000830184610203565b92915050565b600080fd5b61023b816101f1565b811461024657600080fd5b50565b60008135905061025881610232565b92915050565b6000602082840312156102745761027361022d565b5b600061028284828501610249565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156102c55780820151818401526020810190506102aa565b60008484015250505050565b6000601f19601f8301169050919050565b60006102ed8261028b565b6102f78185610296565b93506103078185602086016102a7565b610310816102d1565b840191505092915050565b6000602082019050818103600083015261033581846102e2565b905092915050565b600081905092915050565b50565b600061035860008361033d565b915061036382610348565b600082019050919050565b60006103798261034b565b9150819050919050565b600082825260208201905092915050565b7f4661696c656420746f2063616c6c20656d707479206163636f756e742077697460008201527f682076616c756500000000000000000000000000000000000000000000000000602082015250565b60006103f0602783610383565b91506103fb82610394565b604082019050919050565b6000602082019050818103600083015261041f816103e3565b905091905056fea2646970667358221220b5a8409b4a47065b523cc2a5359c3a45cbab6afcc549a7c55c883476739ca31764736f6c63430008180033"
}
66 changes: 66 additions & 0 deletions x/evm/testutil/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,72 @@ func (suite *TestSuite) TransferERC20Token(
return ercTransferTx, rsp, nil
}

func (suite *TestSuite) TransferValue(
from, to common.Address,
amount *big.Int,

Check warning on line 391 in x/evm/testutil/suite.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

unused-parameter: parameter 'amount' seems to be unused, consider removing or renaming it as _ (revive)
) (*types.MsgEthereumTx, *types.MsgEthereumTxResponse, error) {
ctx := sdk.WrapSDKContext(suite.Ctx)
chainID := suite.App.EvmKeeper.ChainID()

args, err := json.Marshal(&types.TransactionArgs{
To: &to,
From: &from,
})
if err != nil {
return nil, nil, err
}
res, err := suite.QueryClient.EstimateGas(ctx, &types.EthCallRequest{
Args: args,
GasCap: 25_000_000,
ProposerAddress: suite.Ctx.BlockHeader().ProposerAddress,
})
if err != nil {
return nil, nil, err
}

nonce := suite.App.EvmKeeper.GetNonce(suite.Ctx, suite.Address)

var nativeTransferTx *types.MsgEthereumTx
if suite.EnableFeemarket {
nativeTransferTx = types.NewTx(
chainID,
nonce,
&to,
nil,
res.Gas,
nil,
suite.App.FeeMarketKeeper.GetBaseFee(suite.Ctx),
big.NewInt(1),
nil,
&ethtypes.AccessList{}, // accesses
)
} else {
nativeTransferTx = types.NewTx(
chainID,
nonce,
&to,
nil,
res.Gas,
nil,
nil, nil,
nil,
nil,
)
}

nativeTransferTx.From = suite.Address.Hex()
err = nativeTransferTx.Sign(ethtypes.LatestSignerForChainID(chainID), suite.Signer)
if err != nil {
return nil, nil, err
}
rsp, err := suite.App.EvmKeeper.EthereumTx(ctx, nativeTransferTx)
if err != nil {
return nil, rsp, err
}

return nativeTransferTx, rsp, nil
}

// DeployTestMessageCall deploy a test erc20 contract and returns the contract address
func (suite *TestSuite) DeployTestMessageCall(t require.TestingT) common.Address {
ctx := sdk.WrapSDKContext(suite.Ctx)
Expand Down

0 comments on commit 9957478

Please sign in to comment.