Skip to content

Commit

Permalink
test: Add EIP-158 & EIP-161 self destruct test
Browse files Browse the repository at this point in the history
  • Loading branch information
drklee3 committed Feb 27, 2024
1 parent 876f361 commit 30f3a2d
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 6 deletions.
2 changes: 1 addition & 1 deletion contract/contracts/EIP161Test.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
pragma solidity ^0.8.0;

contract EIP161Test {
function selfDestructTo(address target) public {
function selfDestructTo(address target) public payable {
// This contract will self-destruct and send its balance to the target address
selfdestruct(payable(target));
}
Expand Down
74 changes: 74 additions & 0 deletions x/evm/keeper/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,77 @@ func (suite *IntegrationTestSuite) TestEIP161_CallGas() {
)
})
}

// Same as TestEIP161_CallGas but with self destruct
func (suite *IntegrationTestSuite) TestEIP161_SuicideGas() {
suite.MintCoinsForAccount(
suite.Ctx,
sdk.AccAddress(suite.Address.Bytes()),
sdk.NewCoins(
sdk.NewCoin(types.AttoPhoton, sdk.NewInt(100000000000)),
),
)

addr := suite.DeployContract(testutil.EIP161TestContract)

// Non-existent account
targetAddr := common.Address{10}
targetAcc := suite.App.EvmKeeper.GetAccount(suite.Ctx, targetAddr)
suite.Require().Nil(targetAcc, "target should not exist")

value := big.NewInt(10000)

var gasUsed1 uint64

suite.Run("suicide - non-existent destination", func() {
_, rsp, err := suite.CallContract(
testutil.EIP161TestContract,
addr,
value, // >0 value transfer
"selfDestructTo",
targetAddr,
)
suite.Require().NoError(err)
suite.Require().Empty(rsp.VmError)

gasUsed1 = rsp.GasUsed
})

// Deploy again since contract self destructed
addr = suite.DeployContract(testutil.EIP161TestContract)

suite.Run("suicide - existing destination", func() {
targetAcc := suite.App.EvmKeeper.GetAccount(suite.Ctx, targetAddr)
suite.Require().NotNil(targetAcc, "target should exist")

_, rsp, err := suite.CallContract(
testutil.EIP161TestContract,
addr,
value, // >0 value transfer
"selfDestructTo",
targetAddr, // same target
)
suite.Require().NoError(err)
suite.Require().Empty(rsp.VmError)

// Check destination balances
targetAccAfter := suite.App.EvmKeeper.GetAccount(suite.Ctx, targetAddr)
suite.Require().Equal(
new(big.Int).Add(targetAcc.Balance, value),
targetAccAfter.Balance,
"balance should be transferred",
)

// Check gas
suite.Require().Greater(
gasUsed1,
rsp.GasUsed,
"first call should use more gas - created account",
)
suite.Require().GreaterOrEqual(
gasUsed1,
rsp.GasUsed+gethparams.CallNewAccountGas,
"EIP-161: additional 25k gas charge for first call",
)
})
}
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\":\"nonpayable\",\"type\":\"function\"}]",
"bin": "608060405234801561001057600080fd5b506103bb806100206000396000f3fe6080604052600436106100295760003560e01c80636f43e2db1461002e578063a28bf7cc1461005e575b600080fd5b610048600480360381019061004391906101bd565b610087565b604051610055919061027a565b60405180910390f35b34801561006a57600080fd5b50610085600480360381019061008091906101bd565b610141565b005b60606000808373ffffffffffffffffffffffffffffffffffffffff16346040516100b0906102cd565b60006040518083038185875af1925050503d80600081146100ed576040519150601f19603f3d011682016040523d82523d6000602084013e6100f2565b606091505b509150915081610137576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012e90610365565b60405180910390fd5b8092505050919050565b8073ffffffffffffffffffffffffffffffffffffffff16ff5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061018a8261015f565b9050919050565b61019a8161017f565b81146101a557600080fd5b50565b6000813590506101b781610191565b92915050565b6000602082840312156101d3576101d261015a565b5b60006101e1848285016101a8565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610224578082015181840152602081019050610209565b60008484015250505050565b6000601f19601f8301169050919050565b600061024c826101ea565b61025681856101f5565b9350610266818560208601610206565b61026f81610230565b840191505092915050565b600060208201905081810360008301526102948184610241565b905092915050565b600081905092915050565b50565b60006102b760008361029c565b91506102c2826102a7565b600082019050919050565b60006102d8826102aa565b9150819050919050565b600082825260208201905092915050565b7f4661696c656420746f2063616c6c20656d707479206163636f756e742077697460008201527f682076616c756500000000000000000000000000000000000000000000000000602082015250565b600061034f6027836102e2565b915061035a826102f3565b604082019050919050565b6000602082019050818103600083015261037e81610342565b905091905056fea2646970667358221220cfb5ccd351026e6ecddfda020c8ce00e3714e0a5722fd897396563e259d8b1db64736f6c63430008180033"
"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"
}
7 changes: 4 additions & 3 deletions x/evm/testutil/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
// embed compiled smart contract
_ "embed"
"encoding/json"
"fmt"
"math/big"

sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -137,7 +138,7 @@ func (suite *TestSuite) CallContract(
ProposerAddress: suite.Ctx.BlockHeader().ProposerAddress,
})
if err != nil {
return nil, nil, err
return nil, nil, fmt.Errorf("EstimateGas failed: %w", err)
}

nonce := suite.App.EvmKeeper.GetNonce(suite.Ctx, suite.Address)
Expand Down Expand Up @@ -173,11 +174,11 @@ func (suite *TestSuite) CallContract(
ercTransferTx.From = suite.Address.Hex()
err = ercTransferTx.Sign(ethtypes.LatestSignerForChainID(chainID), suite.Signer)
if err != nil {
return nil, nil, err
return nil, nil, fmt.Errorf("failed Sign: %w", err)
}
rsp, err := suite.App.EvmKeeper.EthereumTx(ctx, ercTransferTx)
if err != nil {
return nil, rsp, err
return nil, rsp, fmt.Errorf("failed EthereumTx: %w", err)
}

return ercTransferTx, rsp, nil
Expand Down

0 comments on commit 30f3a2d

Please sign in to comment.