From ef00a1f9325ca614c028c6c930f54f34bfa81d82 Mon Sep 17 00:00:00 2001 From: Wasif Iqbal Date: Thu, 7 Sep 2023 21:24:08 -0500 Subject: [PATCH] Add fuzz tests for transient storage and account touch operations --- miner/algo_common_test.go | 7 +- miner/algo_state_test.go | 193 ++++++++++++++++-- miner/contract_simulator_test.go | 248 ++++++++++++----------- miner/env_changes_test.go | 3 +- miner/state_fuzz_test_abigen_bindings.go | 56 ++++- miner/testdata/state_fuzz_test.abi | 2 +- 6 files changed, 366 insertions(+), 143 deletions(-) diff --git a/miner/algo_common_test.go b/miner/algo_common_test.go index e3372626f0..0ac114ebb2 100644 --- a/miner/algo_common_test.go +++ b/miner/algo_common_test.go @@ -41,7 +41,12 @@ type signerList struct { } func simulateBundle(env *environment, bundle types.MevBundle, chData chainData, interrupt *int32) (types.SimulatedBundle, error) { - stateDB := env.state.Copy() + // NOTE(wazzymandias): We are referencing the environment StateDB here - notice that it is not a copy. + // For test scenarios where bundles depend on previous bundle transactions to succeed, it is + // necessary to reference the same StateDB in order to avoid nonce too high errors. + // As a result, it is recommended that the caller make a copy before invoking this function, in order to + // ensure transaction serializability across bundles. + stateDB := env.state gasPool := new(core.GasPool).AddGas(env.header.GasLimit) var totalGasUsed uint64 diff --git a/miner/algo_state_test.go b/miner/algo_state_test.go index 636d13553f..3f51430d71 100644 --- a/miner/algo_state_test.go +++ b/miner/algo_state_test.go @@ -3,12 +3,14 @@ package miner import ( "bytes" "context" + "crypto/ecdsa" "crypto/rand" "encoding/hex" "fmt" "math/big" mathrand "math/rand" "testing" + "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" @@ -24,19 +26,26 @@ import ( // NOTE(wazzymandias): Below is a FuzzTest contract written in Solidity and shown here as reference code // for the generated abi and bytecode used for testing. -// The generated abi can be found in the `testdata` directory. +// The generated abi can be found in the `testdata` directory in `state_fuzz_test.abi`. // The abi, bytecode, and Go bindings were generated using the following commands: // - docker run -v ${STATE_FUZZ_TEST_CONTRACT_DIRECTORY}:/sources // ethereum/solc:0.8.19 -o /sources/output --abi --bin /sources/StateFuzzTest.sol // - go run ./cmd/abigen/ --bin ${TARGET_STATE_FUZZ_TEST_BIN_PATH} --abi ${TARGET_STATE_FUZZ_TEST_ABI_PATH} // --pkg statefuzztest --out=state_fuzz_test_abigen_bindings.go const StateFuzzTestSolidity = ` +// SPDX-License-Identifier: MIT pragma solidity 0.8.19; contract StateFuzzTest { mapping(address => uint256) public balances; mapping(bytes32 => bytes) public storageData; mapping(address => bool) public isSelfDestructed; + mapping(address => uint256) private refunds; + + function addThenWithdrawRefund(uint256 amount) external payable { + refunds[msg.sender] += amount; + payable(msg.sender).transfer(amount); + } function createObject(bytes32 key, bytes memory value) public { storageData[key] = value; @@ -59,9 +68,12 @@ contract StateFuzzTest { storageData[key] = newValue; } - function touchContract(address contractAddress) public view returns (bytes32) { - return extcodehash(contractAddress); - } + function touchContract(address contractAddress) public view returns (bytes32 codeHash) { + assembly { + codeHash := extcodehash(contractAddress) + } + return codeHash; + } } ` @@ -173,6 +185,50 @@ func selfDestructFuzzTestContract(chainID *big.Int, nonce uint64, to common.Addr }, nil } +func touchAccountFuzzTestContract(chainID *big.Int, nonce uint64, address common.Address) (types.TxData, error) { + abi, err := StatefuzztestMetaData.GetAbi() + if err != nil { + return nil, err + } + + data, err := abi.Pack("touchContract", address) + if err != nil { + return nil, err + } + + return &types.DynamicFeeTx{ + ChainID: chainID, + Nonce: nonce, + Gas: 100_000, + GasFeeCap: big.NewInt(1), + To: (*common.Address)(address[:]), + Value: big.NewInt(0), + Data: data, + }, nil +} + +func addThenWithdrawRefundFuzzTestContract(chainID *big.Int, nonce uint64, to common.Address, value *big.Int) (types.TxData, error) { + abi, err := StatefuzztestMetaData.GetAbi() + if err != nil { + return nil, err + } + + data, err := abi.Pack("addThenWithdrawRefund", value) + if err != nil { + return nil, err + } + + return &types.DynamicFeeTx{ + ChainID: chainID, + Nonce: nonce, + Gas: 400_000, + GasFeeCap: big.NewInt(1), + To: (*common.Address)(to[:]), + Value: value, + Data: data, + }, nil +} + const ( Baseline = 0 SingleSnapshot = 1 @@ -437,7 +493,8 @@ func TestStateComparisons(t *testing.T) { BlockNumber: header.Number, } - simBundle, err := simulateBundle(env, mevBundle, chData, nil) + envCopy := env.copy() + simBundle, err := simulateBundle(envCopy, mevBundle, chData, nil) require.NoError(t, err, "can't simulate bundle: %v", err) switch i { @@ -654,6 +711,7 @@ func TestBundles(t *testing.T) { for tcIdx, tc := range testContexts { backend := simulations[tcIdx] + // deploy fuzz test smart contract across all the account addresses we wish to test t.Run(fmt.Sprintf("%s-create-object", tc.Name), func(t *testing.T) { signers := tc.signers for signerIdx, pk := range signers.signers { @@ -707,14 +765,41 @@ func TestBundles(t *testing.T) { case Baseline: actualReceipt, _, err = tc.envDiff.commitTx(actualTx, tc.chainData) tc.envDiff.applyToBaseEnv() + signer := tc.envDiff.baseEnvironment.signer + from, senderErr := types.Sender(signer, actualTx) + require.NoError(t, senderErr) + + if err == nil { + expectedNonce := actualTx.Nonce() + 1 + actualNonce := tc.envDiff.baseEnvironment.state.GetNonce(from) + require.Equal(t, expectedNonce, actualNonce) + } else { + expectedNonce := actualTx.Nonce() - 1 + actualNonce := tc.envDiff.baseEnvironment.state.GetNonce(from) + require.Equal(t, expectedNonce, actualNonce) + } case SingleSnapshot: err = tc.changes.env.state.NewMultiTxSnapshot() require.NoError(t, err) - actualReceipt, _, err = tc.changes.commitTx(actualTx, tc.chainData) + var commitErr error + actualReceipt, _, commitErr = tc.changes.commitTx(actualTx, tc.chainData) require.NoError(t, err) err = tc.changes.apply() + + signer := tc.changes.env.signer + from, senderErr := types.Sender(signer, actualTx) + require.NoError(t, senderErr) + if commitErr == nil { + expectedNonce := actualTx.Nonce() + 1 + actualNonce := tc.changes.env.state.GetNonce(from) + require.Equal(t, expectedNonce, actualNonce) + } else { + expectedNonce := actualTx.Nonce() - 1 + actualNonce := tc.changes.env.state.GetNonce(from) + require.Equal(t, expectedNonce, actualNonce) + } case MultiSnapshot: err = tc.changes.env.state.NewMultiTxSnapshot() require.NoError(t, err) @@ -722,13 +807,27 @@ func TestBundles(t *testing.T) { err = tc.changes.env.state.NewMultiTxSnapshot() require.NoError(t, err) - actualReceipt, _, err = tc.changes.commitTx(actualTx, tc.chainData) - require.NoError(t, err) + var commitErr error + actualReceipt, _, commitErr = tc.changes.commitTx(actualTx, tc.chainData) + require.NoError(t, commitErr) err = tc.changes.apply() require.NoError(t, err) err = tc.changes.env.state.MultiTxSnapshotCommit() + + signer := tc.changes.env.signer + from, senderErr := types.Sender(signer, actualTx) + require.NoError(t, senderErr) + if commitErr == nil { + expectedNonce := actualTx.Nonce() + 1 + actualNonce := tc.changes.env.state.GetNonce(from) + require.Equal(t, expectedNonce, actualNonce) + } else { + expectedNonce := actualTx.Nonce() - 1 + actualNonce := tc.changes.env.state.GetNonce(from) + require.Equal(t, expectedNonce, actualNonce) + } } require.NoError(t, err) @@ -751,6 +850,8 @@ func TestBundles(t *testing.T) { // - self-destruct // - reset object // - change storage + // - change transient storage + // - touch account type TransactionOperation int const ( ChangeBalance TransactionOperation = iota @@ -758,21 +859,46 @@ func TestBundles(t *testing.T) { SelfDestruct ResetObject ChangeStorage + ChangeTransientStorage + TouchAccount ) + operations := []TransactionOperation{ + ChangeBalance, + CreateObject, + SelfDestruct, + ResetObject, + ChangeStorage, + ChangeTransientStorage, + TouchAccount, + } const ( - bundleCount = 3 - bundleSize = 10 + bundleCount = 10 + bundleSize = 100 ) + // NOTE(wazzymandias): We make a copy of the signer list before we craft the bundles of transactions. + // The reason is that the pre-bundle signer list will be used to simulate the bundles. + // Using the actual signer list will cause nonce mismatch errors, since we increment nonce + // as we craft the bundles of transactions. + var preBundleSigners = signerList{ + config: testContexts[0].signers.config, + addresses: make([]common.Address, len(testContexts[0].signers.addresses)), + signers: make([]*ecdsa.PrivateKey, len(testContexts[0].signers.signers)), + nonces: make([]uint64, len(testContexts[0].signers.nonces)), + } + copy(preBundleSigners.addresses, testContexts[0].signers.addresses) + copy(preBundleSigners.signers, testContexts[0].signers.signers) + copy(preBundleSigners.nonces, testContexts[0].signers.nonces) + bundles := [bundleCount]types.MevBundle{} for bundleIdx := 0; bundleIdx < bundleCount; bundleIdx++ { transactions := [bundleSize]*types.Transaction{} for txIdx := 0; txIdx < bundleSize; txIdx++ { var ( - // pick a random integer that represents one of the transactions we will create - n = mathrand.Intn(5) - s = testContexts[0].signers - chainID = s.config.ChainID + // pick a random operation that represents one of the transactions we will create + randomOperation = operations[mathrand.Intn(len(operations))] + s = testContexts[0].signers + chainID = s.config.ChainID // choose a random To Address index toAddressRandomIdx = mathrand.Intn(len(s.signers)) // reference the correct nonce for the associated To Address @@ -782,7 +908,7 @@ func TestBundles(t *testing.T) { txData types.TxData err error ) - switch TransactionOperation(n) { + switch randomOperation { case ChangeBalance: // change balance balanceAddressRandomIdx := mathrand.Intn(len(s.signers)) balanceAddress := s.addresses[balanceAddressRandomIdx] @@ -826,6 +952,18 @@ func TestBundles(t *testing.T) { require.NoError(t, err) txData, err = changeStorageFuzzTestContract(chainID, nonce, fuzzContractAddress, changeStorageObjectKey, value[:]) + + case ChangeTransientStorage: // change transient storage + value := new(big.Int).Rand( + mathrand.New(mathrand.NewSource(time.Now().UnixNano())), big.NewInt(1000000), + ) + require.NoError(t, err) + + txData, err = addThenWithdrawRefundFuzzTestContract(chainID, nonce, toAddress, value) + case TouchAccount: // touch random account + fuzzContractAddress := variantFuzzTestAddresses[0][toAddressRandomIdx] + + txData, err = touchAccountFuzzTestContract(chainID, nonce, fuzzContractAddress) } require.NotNilf(t, txData, "txData is nil for bundle %d, tx %d", bundleIdx, txIdx) require.NoError(t, err) @@ -839,8 +977,13 @@ func TestBundles(t *testing.T) { multi := testContexts[MultiSnapshot] base.signers.nonces[toAddressRandomIdx]++ + testContexts[Baseline].signers = base.signers + single.signers.nonces[toAddressRandomIdx]++ + testContexts[SingleSnapshot].signers = single.signers + multi.signers.nonces[toAddressRandomIdx]++ + testContexts[MultiSnapshot].signers = multi.signers } bundles[bundleIdx] = types.MevBundle{ @@ -859,36 +1002,44 @@ func TestBundles(t *testing.T) { } } + // commit bundles to each test context, with intermittent bundle failures + const bundleFailEveryN = 2 var ( + base = testContexts[0] commitErrMap = map[int]error{ Baseline: nil, SingleSnapshot: nil, MultiSnapshot: nil, } + genesisAlloc = genGenesisAlloc(preBundleSigners, + []common.Address{payProxyAddress, logContractAddress}, [][]byte{payProxyCode, logContractCode}) ) - - base := testContexts[0] - genesisAlloc := genGenesisAlloc(base.signers, - []common.Address{payProxyAddress, logContractAddress}, [][]byte{payProxyCode, logContractCode}) simulatedBundleList, err := simulateBundles(base.chainData.chainConfig, types.CopyHeader(base.env.header), genesisAlloc, bundles[:]) require.NoError(t, err) + require.Len(t, simulatedBundleList, len(bundles)) // commit bundles one by one to each test context to make sure each bundle result is deterministic // apply all to the underlying environment at the end - for _, b := range simulatedBundleList { + for bundleIdx, b := range simulatedBundleList { algoConf := defaultAlgorithmConfig algoConf.EnforceProfit = true + shouldRevert := bundleFailEveryN != 0 && bundleIdx%bundleFailEveryN == 0 for tcIdx, tc := range testContexts { var commitErr error switch tcIdx { case Baseline: + // We don't commit bundle to Baseline if it's meant to fail, in order to ensure that the state + // for SingleSnapshot and MultiSnapshot matches on revert to the baseline state + if shouldRevert { + break + } commitErr = tc.envDiff.commitBundle(&b, tc.chainData, nil, algoConf) case SingleSnapshot, MultiSnapshot: commitErr = tc.changes.commitBundle(&b, tc.chainData, algoConf) - if commitErrMap[Baseline] != nil { + if commitErrMap[Baseline] != nil || shouldRevert { require.NoError(t, tc.changes.env.state.MultiTxSnapshotRevert()) } else { require.NoError(t, tc.changes.env.state.MultiTxSnapshotCommit()) diff --git a/miner/contract_simulator_test.go b/miner/contract_simulator_test.go index 973053fb83..c14c83983b 100644 --- a/miner/contract_simulator_test.go +++ b/miner/contract_simulator_test.go @@ -110,153 +110,167 @@ func parseAbi(t *testing.T, filename string) *abi.ABI { func TestSimulatorState(t *testing.T) { // enableLogging() - t.Cleanup(func() { - testConfig.AlgoType = ALGO_MEV_GETH - testConfig.BuilderTxSigningKey = nil - testConfig.Etherbase = common.Address{} - }) - - testConfig.AlgoType = ALGO_GREEDY - var err error - testConfig.BuilderTxSigningKey, err = crypto.GenerateKey() - require.NoError(t, err) - testConfig.Etherbase = crypto.PubkeyToAddress(testConfig.BuilderTxSigningKey.PublicKey) - - db := rawdb.NewMemoryDatabase() - chainConfig := *params.AllEthashProtocolChanges - chainConfig.ChainID = big.NewInt(31337) - engine := ethash.NewFaker() - - // (not needed I think) chainConfig.LondonBlock = big.NewInt(0) - deployerKey, err := crypto.ToECDSA(hexutil.MustDecode("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")) - deployerAddress := crypto.PubkeyToAddress(deployerKey.PublicKey) - deployerTestAddress := common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8") - alloc := core.GenesisAlloc{deployerAddress: {Balance: new(big.Int).Mul(big.NewInt(10000), bigEther)}, deployerTestAddress: {Balance: new(big.Int).Mul(big.NewInt(10000), bigEther)}} - - testParticipants := NewTestParticipants(5, 5) - alloc = testParticipants.AppendToGenesisAlloc(alloc) - - var genesis = core.Genesis{ - Config: &chainConfig, - Alloc: alloc, - GasLimit: 30000000, - } + algorithmTable := []AlgoType{ALGO_GREEDY, ALGO_GREEDY_BUCKETS, ALGO_GREEDY_MULTISNAP, ALGO_GREEDY_BUCKETS_MULTISNAP} + for _, algo := range algorithmTable { + t.Run(algo.String(), func(t *testing.T) { + t.Cleanup(func() { + testConfig.AlgoType = ALGO_MEV_GETH + testConfig.BuilderTxSigningKey = nil + testConfig.Etherbase = common.Address{} + }) + + testConfig.AlgoType = algo + var err error + testConfig.BuilderTxSigningKey, err = crypto.GenerateKey() + require.NoError(t, err) + testConfig.Etherbase = crypto.PubkeyToAddress(testConfig.BuilderTxSigningKey.PublicKey) + + db := rawdb.NewMemoryDatabase() + defer func() { + require.NoError(t, db.Close()) + }() + + chainConfig := *params.AllEthashProtocolChanges + chainConfig.ChainID = big.NewInt(31337) + engine := ethash.NewFaker() + defer func() { + require.NoError(t, engine.Close()) + }() + + // (not needed I think) chainConfig.LondonBlock = big.NewInt(0) + deployerKey, err := crypto.ToECDSA(hexutil.MustDecode("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")) + require.NoError(t, err) - w, b := newTestWorkerGenesis(t, &chainConfig, engine, db, genesis, 0) - w.setEtherbase(crypto.PubkeyToAddress(testConfig.BuilderTxSigningKey.PublicKey)) + deployerAddress := crypto.PubkeyToAddress(deployerKey.PublicKey) + deployerTestAddress := common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8") + alloc := core.GenesisAlloc{deployerAddress: {Balance: new(big.Int).Mul(big.NewInt(10000), bigEther)}, deployerTestAddress: {Balance: new(big.Int).Mul(big.NewInt(10000), bigEther)}} - simBackend := backends.NewSimulatedBackendChain(db, b.chain) + testParticipants := NewTestParticipants(5, 5) + alloc = testParticipants.AppendToGenesisAlloc(alloc) - univ2FactoryA := NewTContract(t, simBackend, "testdata/univ2factory.abi", univ2FactoryA_Address) - univ2FactoryB := NewTContract(t, simBackend, "testdata/univ2factory.abi", univ2FactoryB_Address) + var genesis = core.Genesis{ + Config: &chainConfig, + Alloc: alloc, + GasLimit: 30000000, + } - wethContract := NewTContract(t, simBackend, "testdata/weth.abi", wethAddress) - daiContract := NewTContract(t, simBackend, "testdata/dai.abi", daiAddress) - atomicSwapContract := NewTContract(t, simBackend, "testdata/swap.abi", atomicSwapAddress) + w, b := newTestWorkerGenesis(t, &chainConfig, engine, db, genesis, 0) + w.setEtherbase(crypto.PubkeyToAddress(testConfig.BuilderTxSigningKey.PublicKey)) - testAddress1Key, _ := crypto.GenerateKey() - testAddress1 := crypto.PubkeyToAddress(testAddress1Key.PublicKey) + simBackend := backends.NewSimulatedBackendChain(db, b.chain) - rand.New(rand.NewSource(10)) + univ2FactoryA := NewTContract(t, simBackend, "testdata/univ2factory.abi", univ2FactoryA_Address) + univ2FactoryB := NewTContract(t, simBackend, "testdata/univ2factory.abi", univ2FactoryB_Address) - deploymentTxs := deployAllContracts(t, deployerKey, b.chain.CurrentHeader().BaseFee) + wethContract := NewTContract(t, simBackend, "testdata/weth.abi", wethAddress) + daiContract := NewTContract(t, simBackend, "testdata/dai.abi", daiAddress) + atomicSwapContract := NewTContract(t, simBackend, "testdata/swap.abi", atomicSwapAddress) - getBaseFee := func() *big.Int { - return new(big.Int).Mul(big.NewInt(2), b.chain.CurrentHeader().BaseFee) - } + testAddress1Key, _ := crypto.GenerateKey() + testAddress1 := crypto.PubkeyToAddress(testAddress1Key.PublicKey) - nonceModFor := big.NewInt(0) - nonceMod := make(map[common.Address]uint64) - getNonce := func(addr common.Address) uint64 { - if nonceModFor.Cmp(b.chain.CurrentHeader().Number) != 0 { - nonceMod = make(map[common.Address]uint64) - nonceModFor.Set(b.chain.CurrentHeader().Number) - } - - cm := nonceMod[addr] - nonceMod[addr] = cm + 1 - return b.txPool.Nonce(addr) + cm - } + rand.New(rand.NewSource(10)) - prepareContractCallTx := func(contract tConctract, signerKey *ecdsa.PrivateKey, method string, args ...interface{}) *types.Transaction { - callData, err := contract.abi.Pack(method, args...) - require.NoError(t, err) + deploymentTxs := deployAllContracts(t, deployerKey, b.chain.CurrentHeader().BaseFee) - fromAddress := crypto.PubkeyToAddress(signerKey.PublicKey) + getBaseFee := func() *big.Int { + return new(big.Int).Mul(big.NewInt(2), b.chain.CurrentHeader().BaseFee) + } - callRes, err := contract.doCall(fromAddress, method, args...) - if err != nil { - t.Errorf("Prepared smart contract call error %s with result %s", err.Error(), string(callRes)) - } + nonceModFor := big.NewInt(0) + nonceMod := make(map[common.Address]uint64) + getNonce := func(addr common.Address) uint64 { + if nonceModFor.Cmp(b.chain.CurrentHeader().Number) != 0 { + nonceMod = make(map[common.Address]uint64) + nonceModFor.Set(b.chain.CurrentHeader().Number) + } - tx, err := types.SignTx(types.NewTransaction(getNonce(fromAddress), contract.address, new(big.Int), 9000000, getBaseFee(), callData), types.HomesteadSigner{}, signerKey) - require.NoError(t, err) + cm := nonceMod[addr] + nonceMod[addr] = cm + 1 + return b.txPool.Nonce(addr) + cm + } - return tx - } + prepareContractCallTx := func(contract tConctract, signerKey *ecdsa.PrivateKey, method string, args ...interface{}) *types.Transaction { + callData, err := contract.abi.Pack(method, args...) + require.NoError(t, err) - buildBlock := func(txs []*types.Transaction, requireTx int) *types.Block { - errs := b.txPool.AddLocals(txs) - for _, err := range errs { - require.NoError(t, err) - } + fromAddress := crypto.PubkeyToAddress(signerKey.PublicKey) - block, _, err := w.getSealingBlock(b.chain.CurrentBlock().Hash(), b.chain.CurrentHeader().Time+12, testAddress1, 0, common.Hash{}, nil, false, nil) - require.NoError(t, err) - require.NotNil(t, block) - if requireTx != -1 { - require.Equal(t, requireTx, len(block.Transactions())) - } - _, err = b.chain.InsertChain([]*types.Block{block}) - require.NoError(t, err) - return block - } + callRes, err := contract.doCall(fromAddress, method, args...) + if err != nil { + t.Errorf("Prepared smart contract call error %s with result %s", err.Error(), string(callRes)) + } - buildBlock(deploymentTxs, len(deploymentTxs)+1) - require.Equal(t, uint64(18), b.txPool.Nonce(deployerAddress)) - require.Equal(t, uint64(3), b.txPool.Nonce(deployerTestAddress)) + tx, err := types.SignTx(types.NewTransaction(getNonce(fromAddress), contract.address, new(big.Int), 9000000, getBaseFee(), callData), types.HomesteadSigner{}, signerKey) + require.NoError(t, err) - // Mint tokens - require.NoError(t, err) + return tx + } - approveTxs := []*types.Transaction{} + buildBlock := func(txs []*types.Transaction, requireTx int) *types.Block { + errs := b.txPool.AddLocals(txs) + for _, err := range errs { + require.NoError(t, err) + } - adminApproveTxWeth := prepareContractCallTx(wethContract, deployerKey, "approve", atomicSwapContract.address, ethmath.MaxBig256) - approveTxs = append(approveTxs, adminApproveTxWeth) - adminApproveTxDai := prepareContractCallTx(daiContract, deployerKey, "approve", atomicSwapContract.address, ethmath.MaxBig256) - approveTxs = append(approveTxs, adminApproveTxDai) + block, _, err := w.getSealingBlock(b.chain.CurrentBlock().Hash(), b.chain.CurrentHeader().Time+12, testAddress1, 0, common.Hash{}, nil, false, nil) + require.NoError(t, err) + require.NotNil(t, block) + if requireTx != -1 { + require.Equal(t, requireTx, len(block.Transactions())) + } + _, err = b.chain.InsertChain([]*types.Block{block}) + require.NoError(t, err) + return block + } - for _, spender := range []TestParticipant{testParticipants.users[0], testParticipants.searchers[0]} { - mintTx := prepareContractCallTx(daiContract, deployerKey, "mint", spender.address, new(big.Int).Mul(bigEther, big.NewInt(50000))) - approveTxs = append(approveTxs, mintTx) + buildBlock(deploymentTxs, len(deploymentTxs)+1) + require.Equal(t, uint64(18), b.txPool.Nonce(deployerAddress)) + require.Equal(t, uint64(3), b.txPool.Nonce(deployerTestAddress)) - depositTx, err := types.SignTx(types.NewTransaction(getNonce(spender.address), wethContract.address, new(big.Int).Mul(bigEther, big.NewInt(1000)), 9000000, getBaseFee(), hexutil.MustDecode("0xd0e30db0")), types.HomesteadSigner{}, spender.key) - require.NoError(t, err) - approveTxs = append(approveTxs, depositTx) + // Mint tokens + require.NoError(t, err) - spenderApproveTxWeth := prepareContractCallTx(wethContract, spender.key, "approve", atomicSwapContract.address, ethmath.MaxBig256) - approveTxs = append(approveTxs, spenderApproveTxWeth) + approveTxs := []*types.Transaction{} - spenderApproveTxDai := prepareContractCallTx(daiContract, spender.key, "approve", atomicSwapContract.address, ethmath.MaxBig256) - approveTxs = append(approveTxs, spenderApproveTxDai) - } + adminApproveTxWeth := prepareContractCallTx(wethContract, deployerKey, "approve", atomicSwapContract.address, ethmath.MaxBig256) + approveTxs = append(approveTxs, adminApproveTxWeth) + adminApproveTxDai := prepareContractCallTx(daiContract, deployerKey, "approve", atomicSwapContract.address, ethmath.MaxBig256) + approveTxs = append(approveTxs, adminApproveTxDai) - buildBlock(approveTxs, len(approveTxs)+1) + for _, spender := range []TestParticipant{testParticipants.users[0], testParticipants.searchers[0]} { + mintTx := prepareContractCallTx(daiContract, deployerKey, "mint", spender.address, new(big.Int).Mul(bigEther, big.NewInt(50000))) + approveTxs = append(approveTxs, mintTx) - amtIn := new(big.Int).Mul(bigEther, big.NewInt(50)) + depositTx, err := types.SignTx(types.NewTransaction(getNonce(spender.address), wethContract.address, new(big.Int).Mul(bigEther, big.NewInt(1000)), 9000000, getBaseFee(), hexutil.MustDecode("0xd0e30db0")), types.HomesteadSigner{}, spender.key) + require.NoError(t, err) + approveTxs = append(approveTxs, depositTx) - userSwapTx := prepareContractCallTx(atomicSwapContract, testParticipants.users[0].key, "swap", []common.Address{wethContract.address, daiContract.address}, amtIn, univ2FactoryA.address, testParticipants.users[0].address, false) + spenderApproveTxWeth := prepareContractCallTx(wethContract, spender.key, "approve", atomicSwapContract.address, ethmath.MaxBig256) + approveTxs = append(approveTxs, spenderApproveTxWeth) - backrunTxData, err := atomicSwapContract.abi.Pack("backrun", daiContract.address, univ2FactoryB.address, univ2FactoryA.address, new(big.Int).Div(amtIn, big.NewInt(2))) - require.NoError(t, err) + spenderApproveTxDai := prepareContractCallTx(daiContract, spender.key, "approve", atomicSwapContract.address, ethmath.MaxBig256) + approveTxs = append(approveTxs, spenderApproveTxDai) + } - backrunTx, err := types.SignTx(types.NewTransaction(getNonce(testParticipants.searchers[0].address), atomicSwapContract.address, new(big.Int), 9000000, getBaseFee(), backrunTxData), types.HomesteadSigner{}, testParticipants.searchers[0].key) - require.NoError(t, err) + buildBlock(approveTxs, len(approveTxs)+1) + + amtIn := new(big.Int).Mul(bigEther, big.NewInt(50)) - targetBlockNumber := new(big.Int).Set(b.chain.CurrentHeader().Number) - targetBlockNumber.Add(targetBlockNumber, big.NewInt(1)) - b.txPool.AddMevBundle(types.Transactions{userSwapTx, backrunTx}, targetBlockNumber, uuid.UUID{}, common.Address{}, 0, 0, nil) - buildBlock([]*types.Transaction{}, 3) + userSwapTx := prepareContractCallTx(atomicSwapContract, testParticipants.users[0].key, "swap", []common.Address{wethContract.address, daiContract.address}, amtIn, univ2FactoryA.address, testParticipants.users[0].address, false) + + backrunTxData, err := atomicSwapContract.abi.Pack("backrun", daiContract.address, univ2FactoryB.address, univ2FactoryA.address, new(big.Int).Div(amtIn, big.NewInt(2))) + require.NoError(t, err) + + backrunTx, err := types.SignTx(types.NewTransaction(getNonce(testParticipants.searchers[0].address), atomicSwapContract.address, new(big.Int), 9000000, getBaseFee(), backrunTxData), types.HomesteadSigner{}, testParticipants.searchers[0].key) + require.NoError(t, err) + + targetBlockNumber := new(big.Int).Set(b.chain.CurrentHeader().Number) + targetBlockNumber.Add(targetBlockNumber, big.NewInt(1)) + b.txPool.AddMevBundle(types.Transactions{userSwapTx, backrunTx}, targetBlockNumber, uuid.UUID{}, common.Address{}, 0, 0, nil) + buildBlock([]*types.Transaction{}, 3) + }) + } } type tConctract struct { diff --git a/miner/env_changes_test.go b/miner/env_changes_test.go index decb179dca..6396c9b94a 100644 --- a/miner/env_changes_test.go +++ b/miner/env_changes_test.go @@ -71,7 +71,8 @@ func TestBundleCommitSnaps(t *testing.T) { BlockNumber: env.header.Number, } - simBundle, err := simulateBundle(env, bundle, chData, nil) + envCopy := env.copy() + simBundle, err := simulateBundle(envCopy, bundle, chData, nil) if err != nil { t.Fatal("Failed to simulate bundle", err) } diff --git a/miner/state_fuzz_test_abigen_bindings.go b/miner/state_fuzz_test_abigen_bindings.go index 1f2d076628..06a1a70039 100644 --- a/miner/state_fuzz_test_abigen_bindings.go +++ b/miner/state_fuzz_test_abigen_bindings.go @@ -31,8 +31,8 @@ var ( // StatefuzztestMetaData contains all meta data concerning the Statefuzztest contract. var StatefuzztestMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balances\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"changeBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"newValue\",\"type\":\"bytes\"}],\"name\":\"changeStorage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"value\",\"type\":\"bytes\"}],\"name\":\"createObject\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isSelfDestructed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"}],\"name\":\"resetObject\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"selfDestruct\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"storageData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b50610b1f806100206000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063b0d50e381161005b578063b0d50e38146100ff578063c522de441461012f578063d58010651461015f578063f529d4481461017b57610088565b806327e235e31461008d5780637a5ae62e146100bd5780639cb8a26a146100d9578063a2601e0a146100e3575b600080fd5b6100a760048036038101906100a29190610462565b610197565b6040516100b491906104a8565b60405180910390f35b6100d760048036038101906100d291906104f9565b6101af565b005b6100e16101d1565b005b6100fd60048036038101906100f8919061066c565b610242565b005b61011960048036038101906101149190610462565b610267565b60405161012691906106e3565b60405180910390f35b610149600480360381019061014491906104f9565b610287565b604051610156919061077d565b60405180910390f35b6101796004803603810190610174919061066c565b610327565b005b610195600480360381019061019091906107cb565b61034c565b005b60006020528060005260406000206000915090505481565b6001600082815260200190815260200160002060006101ce9190610393565b50565b6001600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff16ff5b806001600084815260200190815260200160002090816102629190610a17565b505050565b60026020528060005260406000206000915054906101000a900460ff1681565b600160205280600052604060002060009150905080546102a69061083a565b80601f01602080910402602001604051908101604052809291908181526020018280546102d29061083a565b801561031f5780601f106102f45761010080835404028352916020019161031f565b820191906000526020600020905b81548152906001019060200180831161030257829003601f168201915b505050505081565b806001600084815260200190815260200160002090816103479190610a17565b505050565b806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b50805461039f9061083a565b6000825580601f106103b157506103d0565b601f0160209004906000526020600020908101906103cf91906103d3565b5b50565b5b808211156103ec5760008160009055506001016103d4565b5090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061042f82610404565b9050919050565b61043f81610424565b811461044a57600080fd5b50565b60008135905061045c81610436565b92915050565b600060208284031215610478576104776103fa565b5b60006104868482850161044d565b91505092915050565b6000819050919050565b6104a28161048f565b82525050565b60006020820190506104bd6000830184610499565b92915050565b6000819050919050565b6104d6816104c3565b81146104e157600080fd5b50565b6000813590506104f3816104cd565b92915050565b60006020828403121561050f5761050e6103fa565b5b600061051d848285016104e4565b91505092915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61057982610530565b810181811067ffffffffffffffff8211171561059857610597610541565b5b80604052505050565b60006105ab6103f0565b90506105b78282610570565b919050565b600067ffffffffffffffff8211156105d7576105d6610541565b5b6105e082610530565b9050602081019050919050565b82818337600083830152505050565b600061060f61060a846105bc565b6105a1565b90508281526020810184848401111561062b5761062a61052b565b5b6106368482856105ed565b509392505050565b600082601f83011261065357610652610526565b5b81356106638482602086016105fc565b91505092915050565b60008060408385031215610683576106826103fa565b5b6000610691858286016104e4565b925050602083013567ffffffffffffffff8111156106b2576106b16103ff565b5b6106be8582860161063e565b9150509250929050565b60008115159050919050565b6106dd816106c8565b82525050565b60006020820190506106f860008301846106d4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561073857808201518184015260208101905061071d565b60008484015250505050565b600061074f826106fe565b6107598185610709565b935061076981856020860161071a565b61077281610530565b840191505092915050565b600060208201905081810360008301526107978184610744565b905092915050565b6107a88161048f565b81146107b357600080fd5b50565b6000813590506107c58161079f565b92915050565b600080604083850312156107e2576107e16103fa565b5b60006107f08582860161044d565b9250506020610801858286016107b6565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061085257607f821691505b6020821081036108655761086461080b565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026108cd7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610890565b6108d78683610890565b95508019841693508086168417925050509392505050565b6000819050919050565b600061091461090f61090a8461048f565b6108ef565b61048f565b9050919050565b6000819050919050565b61092e836108f9565b61094261093a8261091b565b84845461089d565b825550505050565b600090565b61095761094a565b610962818484610925565b505050565b5b818110156109865761097b60008261094f565b600181019050610968565b5050565b601f8211156109cb5761099c8161086b565b6109a584610880565b810160208510156109b4578190505b6109c86109c085610880565b830182610967565b50505b505050565b600082821c905092915050565b60006109ee600019846008026109d0565b1980831691505092915050565b6000610a0783836109dd565b9150826002028217905092915050565b610a20826106fe565b67ffffffffffffffff811115610a3957610a38610541565b5b610a43825461083a565b610a4e82828561098a565b600060209050601f831160018114610a815760008415610a6f578287015190505b610a7985826109fb565b865550610ae1565b601f198416610a8f8661086b565b60005b82811015610ab757848901518255600182019150602085019450602081019050610a92565b86831015610ad45784890151610ad0601f8916826109dd565b8355505b6001600288020188555050505b50505050505056fea26469706673582212202f3e2761204e887bab7c8f092e2346bad94e865f80979db9a6915f9d2bdbc03c64736f6c63430008130033", + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"addThenWithdrawRefund\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balances\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"changeBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"newValue\",\"type\":\"bytes\"}],\"name\":\"changeStorage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"value\",\"type\":\"bytes\"}],\"name\":\"createObject\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isSelfDestructed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"}],\"name\":\"resetObject\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"selfDestruct\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"storageData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"}],\"name\":\"touchContract\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"codeHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50610d4e806100206000396000f3fe6080604052600436106100915760003560e01c8063a2601e0a11610059578063a2601e0a1461016c578063b0d50e3814610195578063c522de44146101d2578063d58010651461020f578063f529d4481461023857610091565b806327e235e3146100965780633e978173146100d3578063798d40e3146100ef5780637a5ae62e1461012c5780639cb8a26a14610155575b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b891906105d7565b610261565b6040516100ca919061061d565b60405180910390f35b6100ed60048036038101906100e89190610664565b610279565b005b3480156100fb57600080fd5b50610116600480360381019061011191906105d7565b610319565b60405161012391906106aa565b60405180910390f35b34801561013857600080fd5b50610153600480360381019061014e91906106f1565b610324565b005b34801561016157600080fd5b5061016a610346565b005b34801561017857600080fd5b50610193600480360381019061018e9190610864565b6103b7565b005b3480156101a157600080fd5b506101bc60048036038101906101b791906105d7565b6103dc565b6040516101c991906108db565b60405180910390f35b3480156101de57600080fd5b506101f960048036038101906101f491906106f1565b6103fc565b6040516102069190610975565b60405180910390f35b34801561021b57600080fd5b5061023660048036038101906102319190610864565b61049c565b005b34801561024457600080fd5b5061025f600480360381019061025a9190610997565b6104c1565b005b60006020528060005260406000206000915090505481565b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546102c89190610a06565b925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610315573d6000803e3d6000fd5b5050565b6000813f9050919050565b6001600082815260200190815260200160002060006103439190610508565b50565b6001600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff16ff5b806001600084815260200190815260200160002090816103d79190610c46565b505050565b60026020528060005260406000206000915054906101000a900460ff1681565b6001602052806000526040600020600091509050805461041b90610a69565b80601f016020809104026020016040519081016040528092919081815260200182805461044790610a69565b80156104945780601f1061046957610100808354040283529160200191610494565b820191906000526020600020905b81548152906001019060200180831161047757829003601f168201915b505050505081565b806001600084815260200190815260200160002090816104bc9190610c46565b505050565b806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b50805461051490610a69565b6000825580601f106105265750610545565b601f0160209004906000526020600020908101906105449190610548565b5b50565b5b80821115610561576000816000905550600101610549565b5090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006105a482610579565b9050919050565b6105b481610599565b81146105bf57600080fd5b50565b6000813590506105d1816105ab565b92915050565b6000602082840312156105ed576105ec61056f565b5b60006105fb848285016105c2565b91505092915050565b6000819050919050565b61061781610604565b82525050565b6000602082019050610632600083018461060e565b92915050565b61064181610604565b811461064c57600080fd5b50565b60008135905061065e81610638565b92915050565b60006020828403121561067a5761067961056f565b5b60006106888482850161064f565b91505092915050565b6000819050919050565b6106a481610691565b82525050565b60006020820190506106bf600083018461069b565b92915050565b6106ce81610691565b81146106d957600080fd5b50565b6000813590506106eb816106c5565b92915050565b6000602082840312156107075761070661056f565b5b6000610715848285016106dc565b91505092915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61077182610728565b810181811067ffffffffffffffff821117156107905761078f610739565b5b80604052505050565b60006107a3610565565b90506107af8282610768565b919050565b600067ffffffffffffffff8211156107cf576107ce610739565b5b6107d882610728565b9050602081019050919050565b82818337600083830152505050565b6000610807610802846107b4565b610799565b90508281526020810184848401111561082357610822610723565b5b61082e8482856107e5565b509392505050565b600082601f83011261084b5761084a61071e565b5b813561085b8482602086016107f4565b91505092915050565b6000806040838503121561087b5761087a61056f565b5b6000610889858286016106dc565b925050602083013567ffffffffffffffff8111156108aa576108a9610574565b5b6108b685828601610836565b9150509250929050565b60008115159050919050565b6108d5816108c0565b82525050565b60006020820190506108f060008301846108cc565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610930578082015181840152602081019050610915565b60008484015250505050565b6000610947826108f6565b6109518185610901565b9350610961818560208601610912565b61096a81610728565b840191505092915050565b6000602082019050818103600083015261098f818461093c565b905092915050565b600080604083850312156109ae576109ad61056f565b5b60006109bc858286016105c2565b92505060206109cd8582860161064f565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610a1182610604565b9150610a1c83610604565b9250828201905080821115610a3457610a336109d7565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610a8157607f821691505b602082108103610a9457610a93610a3a565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302610afc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610abf565b610b068683610abf565b95508019841693508086168417925050509392505050565b6000819050919050565b6000610b43610b3e610b3984610604565b610b1e565b610604565b9050919050565b6000819050919050565b610b5d83610b28565b610b71610b6982610b4a565b848454610acc565b825550505050565b600090565b610b86610b79565b610b91818484610b54565b505050565b5b81811015610bb557610baa600082610b7e565b600181019050610b97565b5050565b601f821115610bfa57610bcb81610a9a565b610bd484610aaf565b81016020851015610be3578190505b610bf7610bef85610aaf565b830182610b96565b50505b505050565b600082821c905092915050565b6000610c1d60001984600802610bff565b1980831691505092915050565b6000610c368383610c0c565b9150826002028217905092915050565b610c4f826108f6565b67ffffffffffffffff811115610c6857610c67610739565b5b610c728254610a69565b610c7d828285610bb9565b600060209050601f831160018114610cb05760008415610c9e578287015190505b610ca88582610c2a565b865550610d10565b601f198416610cbe86610a9a565b60005b82811015610ce657848901518255600182019150602085019450602081019050610cc1565b86831015610d035784890151610cff601f891682610c0c565b8355505b6001600288020188555050505b50505050505056fea2646970667358221220bf0fddc0e0582d2115c83591396205edb56de333d7cc4ef10f8a3d740b137fc464736f6c63430008130033", } // StatefuzztestABI is the input ABI used to generate the binding from. @@ -295,6 +295,58 @@ func (_Statefuzztest *StatefuzztestCallerSession) StorageData(arg0 [32]byte) ([] return _Statefuzztest.Contract.StorageData(&_Statefuzztest.CallOpts, arg0) } +// TouchContract is a free data retrieval call binding the contract method 0x798d40e3. +// +// Solidity: function touchContract(address contractAddress) view returns(bytes32 codeHash) +func (_Statefuzztest *StatefuzztestCaller) TouchContract(opts *bind.CallOpts, contractAddress common.Address) ([32]byte, error) { + var out []interface{} + err := _Statefuzztest.contract.Call(opts, &out, "touchContract", contractAddress) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TouchContract is a free data retrieval call binding the contract method 0x798d40e3. +// +// Solidity: function touchContract(address contractAddress) view returns(bytes32 codeHash) +func (_Statefuzztest *StatefuzztestSession) TouchContract(contractAddress common.Address) ([32]byte, error) { + return _Statefuzztest.Contract.TouchContract(&_Statefuzztest.CallOpts, contractAddress) +} + +// TouchContract is a free data retrieval call binding the contract method 0x798d40e3. +// +// Solidity: function touchContract(address contractAddress) view returns(bytes32 codeHash) +func (_Statefuzztest *StatefuzztestCallerSession) TouchContract(contractAddress common.Address) ([32]byte, error) { + return _Statefuzztest.Contract.TouchContract(&_Statefuzztest.CallOpts, contractAddress) +} + +// AddThenWithdrawRefund is a paid mutator transaction binding the contract method 0x3e978173. +// +// Solidity: function addThenWithdrawRefund(uint256 amount) payable returns() +func (_Statefuzztest *StatefuzztestTransactor) AddThenWithdrawRefund(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _Statefuzztest.contract.Transact(opts, "addThenWithdrawRefund", amount) +} + +// AddThenWithdrawRefund is a paid mutator transaction binding the contract method 0x3e978173. +// +// Solidity: function addThenWithdrawRefund(uint256 amount) payable returns() +func (_Statefuzztest *StatefuzztestSession) AddThenWithdrawRefund(amount *big.Int) (*types.Transaction, error) { + return _Statefuzztest.Contract.AddThenWithdrawRefund(&_Statefuzztest.TransactOpts, amount) +} + +// AddThenWithdrawRefund is a paid mutator transaction binding the contract method 0x3e978173. +// +// Solidity: function addThenWithdrawRefund(uint256 amount) payable returns() +func (_Statefuzztest *StatefuzztestTransactorSession) AddThenWithdrawRefund(amount *big.Int) (*types.Transaction, error) { + return _Statefuzztest.Contract.AddThenWithdrawRefund(&_Statefuzztest.TransactOpts, amount) +} + // ChangeBalance is a paid mutator transaction binding the contract method 0xf529d448. // // Solidity: function changeBalance(address account, uint256 newBalance) returns() diff --git a/miner/testdata/state_fuzz_test.abi b/miner/testdata/state_fuzz_test.abi index fc0178be7b..92bdef0182 100644 --- a/miner/testdata/state_fuzz_test.abi +++ b/miner/testdata/state_fuzz_test.abi @@ -1 +1 @@ -[{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"changeBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"},{"internalType":"bytes","name":"newValue","type":"bytes"}],"name":"changeStorage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"},{"internalType":"bytes","name":"value","type":"bytes"}],"name":"createObject","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isSelfDestructed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"resetObject","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"selfDestruct","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"storageData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"}] \ No newline at end of file +[{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"addThenWithdrawRefund","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"changeBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"},{"internalType":"bytes","name":"newValue","type":"bytes"}],"name":"changeStorage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"},{"internalType":"bytes","name":"value","type":"bytes"}],"name":"createObject","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isSelfDestructed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"resetObject","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"selfDestruct","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"storageData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"touchContract","outputs":[{"internalType":"bytes32","name":"codeHash","type":"bytes32"}],"stateMutability":"view","type":"function"}] \ No newline at end of file