From 2917efcf985a46311960668ec60f8dbac41b6074 Mon Sep 17 00:00:00 2001 From: anishnaik Date: Thu, 3 Aug 2023 15:13:35 -0400 Subject: [PATCH 1/4] update log level for invalid corpus item (#194) --- fuzzing/corpus/corpus.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuzzing/corpus/corpus.go b/fuzzing/corpus/corpus.go index 827a3f58..d8c4d479 100644 --- a/fuzzing/corpus/corpus.go +++ b/fuzzing/corpus/corpus.go @@ -222,7 +222,7 @@ func (c *Corpus) initializeSequences(sequenceFiles *corpusDirectory[calls.CallSe } c.unexecutedCallSequences = append(c.unexecutedCallSequences, sequence) } else { - c.logger.Warn("Corpus item ", colors.Bold, sequenceFileData.fileName, colors.Reset, " disabled due to error when replaying it", sequenceInvalidError) + c.logger.Debug("Corpus item ", colors.Bold, sequenceFileData.fileName, colors.Reset, " disabled due to error when replaying it", sequenceInvalidError) } // Revert chain state to our starting point to test the next sequence. From cd8605e4be0391ab2260cee000045c935dd80091 Mon Sep 17 00:00:00 2001 From: David Pokora Date: Fri, 11 Aug 2023 10:58:38 -0400 Subject: [PATCH 2/4] Update to go-ethereum 1.12.0 (#199) * Updated CallMessage to be compliant with core.Message made in new go-ethereum --------- Co-authored-by: anishnaik --- chain/test_chain.go | 18 +- chain/test_chain_test.go | 64 ++++++- chain/types/block.go | 4 +- chain/vendored/apply_transaction.go | 4 +- compilation/types/source_maps.go | 2 +- fuzzing/calls/call_message.go | 197 +++++++++++--------- fuzzing/calls/call_sequence.go | 16 +- fuzzing/calls/call_sequence_execution.go | 2 +- fuzzing/calls/gen_call_message_json.go | 113 ++++++----- fuzzing/corpus/corpus.go | 8 +- fuzzing/corpus/corpus_test.go | 18 +- fuzzing/executiontracer/execution_tracer.go | 2 +- fuzzing/fuzzer.go | 3 +- fuzzing/fuzzer_worker.go | 23 ++- fuzzing/fuzzer_worker_sequence_generator.go | 8 +- fuzzing/test_case_optimization_provider.go | 4 +- fuzzing/test_case_property_provider.go | 4 +- go.mod | 13 +- go.sum | 56 +----- utils/message_transaction_utils.go | 14 +- 20 files changed, 313 insertions(+), 260 deletions(-) diff --git a/chain/test_chain.go b/chain/test_chain.go index ec60979c..a4466cc7 100644 --- a/chain/test_chain.go +++ b/chain/test_chain.go @@ -89,6 +89,14 @@ func NewTestChain(genesisAlloc core.GenesisAlloc, testChainConfig *config.TestCh return nil, err } + // TODO: go-ethereum doesn't set shanghai start time for THEIR test `ChainConfig` struct. + // Note: We have our own `TestChainConfig` definition that is different (second argument in this function). + // We should allow the user to provide a go-ethereum `ChainConfig` to do custom fork selection, inside of our + // `TestChainConfig` definition. Or we should wrap it in our own struct to simplify the options and not pollute + // our overall medusa project config. + shanghaiTime := uint64(0) + chainConfig.ShanghaiTime = &shanghaiTime + // Create our genesis definition with our default chain config. genesisDefinition := &core.Genesis{ Config: chainConfig, @@ -527,7 +535,7 @@ func (t *TestChain) RevertToBlockNumber(blockNumber uint64) error { // It takes an optional state argument, which is the state to execute the message over. If not provided, the // current pending state (or committed state if none is pending) will be used instead. // The state executed over may be a pending block state. -func (t *TestChain) CallContract(msg core.Message, state *state.StateDB, additionalTracers ...vm.EVMLogger) (*core.ExecutionResult, error) { +func (t *TestChain) CallContract(msg *core.Message, state *state.StateDB, additionalTracers ...vm.EVMLogger) (*core.ExecutionResult, error) { // If our provided state is nil, use our current chain state. if state == nil { state = t.state @@ -537,7 +545,7 @@ func (t *TestChain) CallContract(msg core.Message, state *state.StateDB, additio snapshot := state.Snapshot() // Set infinite balance to the fake caller account - from := state.GetOrNewStateObject(msg.From()) + from := state.GetOrNewStateObject(msg.From) from.SetBalance(math.MaxBig256) // Create our transaction and block contexts for the vm @@ -552,7 +560,7 @@ func (t *TestChain) CallContract(msg core.Message, state *state.StateDB, additio // Create our EVM instance. evm := vm.NewEVM(blockContext, txContext, state, t.chainConfig, vm.Config{ - Debug: true, + //Debug: true, Tracer: extendedTracerRouter, NoBaseFee: true, ConfigExtensions: t.vmConfigExtensions, @@ -672,7 +680,7 @@ func (t *TestChain) PendingBlockCreateWithParameters(blockNumber uint64, blockTi // PendingBlockAddTx takes a message (internal txs) and adds it to the current pending block, updating the header // with relevant execution information. If a pending block was not created, an error is returned. // Returns the constructed block, or an error if one occurred. -func (t *TestChain) PendingBlockAddTx(message core.Message) error { +func (t *TestChain) PendingBlockAddTx(message *core.Message) error { // If we don't have a pending block, return an error if t.pendingBlock == nil { return errors.New("could not add tx to the chain's pending block because no pending block was created") @@ -692,7 +700,7 @@ func (t *TestChain) PendingBlockAddTx(message core.Message) error { // Create our EVM instance. evm := vm.NewEVM(blockContext, core.NewEVMTxContext(message), t.state, t.chainConfig, vm.Config{ - Debug: true, + //Debug: true, Tracer: t.transactionTracerRouter, NoBaseFee: true, ConfigExtensions: t.vmConfigExtensions, diff --git a/chain/test_chain_test.go b/chain/test_chain_test.go index bb049d1c..5c8e6449 100644 --- a/chain/test_chain_test.go +++ b/chain/test_chain_test.go @@ -241,14 +241,26 @@ func TestChainDynamicDeployments(t *testing.T) { // Deploy the currently indexed contract next // Create a message to represent our contract deployment. - msg := types.NewMessage(senders[0], nil, chain.State().GetNonce(senders[0]), big.NewInt(0), chain.BlockGasLimit, big.NewInt(1), big.NewInt(0), big.NewInt(0), contract.InitBytecode, nil, false) + msg := core.Message{ + To: nil, + From: senders[0], + Nonce: chain.State().GetNonce(senders[0]), + Value: big.NewInt(0), + GasLimit: chain.BlockGasLimit, + GasPrice: big.NewInt(1), + GasFeeCap: big.NewInt(0), + GasTipCap: big.NewInt(0), + Data: contract.InitBytecode, + AccessList: nil, + SkipAccountChecks: false, + } // Create a new pending block we'll commit to chain block, err := chain.PendingBlockCreate() assert.NoError(t, err) // Add our transaction to the block - err = chain.PendingBlockAddTx(msg) + err = chain.PendingBlockAddTx(&msg) assert.NoError(t, err) // Commit the pending block to the chain, so it becomes the new head. @@ -354,14 +366,26 @@ func TestChainDeploymentWithArgs(t *testing.T) { assert.NoError(t, err) // Create a message to represent our contract deployment. - msg := types.NewMessage(senders[0], nil, chain.State().GetNonce(senders[0]), big.NewInt(0), chain.BlockGasLimit, big.NewInt(1), big.NewInt(0), big.NewInt(0), msgData, nil, false) + msg := core.Message{ + To: nil, + From: senders[0], + Nonce: chain.State().GetNonce(senders[0]), + Value: big.NewInt(0), + GasLimit: chain.BlockGasLimit, + GasPrice: big.NewInt(1), + GasFeeCap: big.NewInt(0), + GasTipCap: big.NewInt(0), + Data: msgData, + AccessList: nil, + SkipAccountChecks: false, + } // Create a new pending block we'll commit to chain block, err := chain.PendingBlockCreate() assert.NoError(t, err) // Add our transaction to the block - err = chain.PendingBlockAddTx(msg) + err = chain.PendingBlockAddTx(&msg) assert.NoError(t, err) // Commit the pending block to the chain, so it becomes the new head. @@ -451,14 +475,26 @@ func TestChainCloning(t *testing.T) { // Deploy the currently indexed contract next // Create a message to represent our contract deployment. - msg := types.NewMessage(senders[0], nil, chain.State().GetNonce(senders[0]), big.NewInt(0), chain.BlockGasLimit, big.NewInt(1), big.NewInt(0), big.NewInt(0), contract.InitBytecode, nil, false) + msg := core.Message{ + To: nil, + From: senders[0], + Nonce: chain.State().GetNonce(senders[0]), + Value: big.NewInt(0), + GasLimit: chain.BlockGasLimit, + GasPrice: big.NewInt(1), + GasFeeCap: big.NewInt(0), + GasTipCap: big.NewInt(0), + Data: contract.InitBytecode, + AccessList: nil, + SkipAccountChecks: false, + } // Create a new pending block we'll commit to chain block, err := chain.PendingBlockCreate() assert.NoError(t, err) // Add our transaction to the block - err = chain.PendingBlockAddTx(msg) + err = chain.PendingBlockAddTx(&msg) assert.NoError(t, err) // Commit the pending block to the chain, so it becomes the new head. @@ -533,14 +569,26 @@ func TestChainCallSequenceReplayMatchSimple(t *testing.T) { if len(contract.Abi.Constructor.Inputs) == 0 { for i := 0; i < 10; i++ { // Create a message to represent our contract deployment. - msg := types.NewMessage(senders[0], nil, chain.State().GetNonce(senders[0]), big.NewInt(0), chain.BlockGasLimit, big.NewInt(1), big.NewInt(0), big.NewInt(0), contract.InitBytecode, nil, false) + msg := core.Message{ + To: nil, + From: senders[0], + Nonce: chain.State().GetNonce(senders[0]), + Value: big.NewInt(0), + GasLimit: chain.BlockGasLimit, + GasPrice: big.NewInt(1), + GasFeeCap: big.NewInt(0), + GasTipCap: big.NewInt(0), + Data: contract.InitBytecode, + AccessList: nil, + SkipAccountChecks: false, + } // Create a new pending block we'll commit to chain block, err := chain.PendingBlockCreate() assert.NoError(t, err) // Add our transaction to the block - err = chain.PendingBlockAddTx(msg) + err = chain.PendingBlockAddTx(&msg) assert.NoError(t, err) // Commit the pending block to the chain, so it becomes the new head. diff --git a/chain/types/block.go b/chain/types/block.go index 47638e19..754f81ff 100644 --- a/chain/types/block.go +++ b/chain/types/block.go @@ -18,7 +18,7 @@ type Block struct { // of a transaction occurs and can be thought of as an internal EVM transaction. It contains typical transaction // fields plainly (e.g., no transaction signature is included, the sender is derived and simply supplied as a field // in a message). - Messages []core.Message + Messages []*core.Message // MessageResults represents the results recorded while executing transactions. MessageResults []*MessageResults @@ -30,7 +30,7 @@ func NewBlock(header *types.Header) *Block { block := &Block{ Hash: header.Hash(), Header: header, - Messages: make([]core.Message, 0), + Messages: make([]*core.Message, 0), MessageResults: make([]*MessageResults, 0), } return block diff --git a/chain/vendored/apply_transaction.go b/chain/vendored/apply_transaction.go index e9fab99e..2044bf02 100644 --- a/chain/vendored/apply_transaction.go +++ b/chain/vendored/apply_transaction.go @@ -35,7 +35,7 @@ import ( // This executes on an underlying EVM and returns a transaction receipt, or an error if one occurs. // Additional changes: // - Exposed core.ExecutionResult as a return value. -func EVMApplyTransaction(msg Message, config *params.ChainConfig, author *common.Address, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, *ExecutionResult, error) { +func EVMApplyTransaction(msg *Message, config *params.ChainConfig, author *common.Address, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, *ExecutionResult, error) { // Create a new context to be used in the EVM environment. txContext := NewEVMTxContext(msg) evm.Reset(txContext, statedb) @@ -67,7 +67,7 @@ func EVMApplyTransaction(msg Message, config *params.ChainConfig, author *common receipt.GasUsed = result.UsedGas // If the transaction created a contract, store the creation address in the receipt. - if msg.To() == nil { + if msg.To == nil { receipt.ContractAddress = crypto.CreateAddress(evm.TxContext.Origin, tx.Nonce()) } diff --git a/compilation/types/source_maps.go b/compilation/types/source_maps.go index 9804733d..c5a92ad0 100644 --- a/compilation/types/source_maps.go +++ b/compilation/types/source_maps.go @@ -170,7 +170,7 @@ func (s SourceMap) GetInstructionIndexToOffsetLookup(bytecode []byte) ([]int, er operandCount := 0 if op.IsPush() { if op == vm.PUSH0 { - operandCount = 1 + operandCount = 0 } else { operandCount = int(op) - int(vm.PUSH1) + 1 } diff --git a/fuzzing/calls/call_message.go b/fuzzing/calls/call_message.go index de3a856f..47dc0263 100644 --- a/fuzzing/calls/call_message.go +++ b/fuzzing/calls/call_message.go @@ -5,6 +5,7 @@ import ( "github.com/crytic/medusa/logging" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core" coreTypes "github.com/ethereum/go-ethereum/core/types" "golang.org/x/exp/slices" "math/big" @@ -15,91 +16,113 @@ import ( //go:generate go get github.com/fjl/gencodec //go:generate go run github.com/fjl/gencodec -type CallMessage -field-override callMessageMarshaling -out gen_call_message_json.go -// CallMessage implements Ethereum's coreTypes.Message, used to apply EVM/state updates. +// CallMessage implements and extends Ethereum's coreTypes.Message, used to apply EVM/state updates. type CallMessage struct { - // MsgFrom represents a core.Message's from parameter (sender), indicating who sent a transaction/message to the + // From represents a core.Message's from parameter (sender), indicating who sent a transaction/message to the // Ethereum core to apply a state update. - MsgFrom common.Address `json:"from"` + From common.Address `json:"from"` - // MsgTo represents the receiving address for a given core.Message. - MsgTo *common.Address `json:"to"` + // To represents the receiving address for a given core.Message. + To *common.Address `json:"to"` - // MsgNonce represents the core.Message sender's nonce - MsgNonce uint64 `json:"nonce"` + // Nonce represents the core.Message sender's nonce + Nonce uint64 `json:"nonce"` - // MsgValue represents ETH value to be sent to the receiver of the message. - MsgValue *big.Int `json:"value"` + // Value represents ETH value to be sent to the receiver of the message. + Value *big.Int `json:"value"` - // MsgGas represents the maximum amount of gas the sender is willing to spend to cover the cost of executing the + // GasLimit represents the maximum amount of gas the sender is willing to spend to cover the cost of executing the // message or transaction. - MsgGas uint64 `json:"gas"` + GasLimit uint64 `json:"gasLimit"` - // MsgGasPrice represents the price which the sender is willing to pay for each unit of gas used during execution + // GasPrice represents the price which the sender is willing to pay for each unit of gas used during execution // of the message. - MsgGasPrice *big.Int `json:"gasPrice"` + GasPrice *big.Int `json:"gasPrice"` - // MsgGasFeeCap represents the maximum fee to enforce for gas related costs (related to 1559 transaction executed). + // GasFeeCap represents the maximum fee to enforce for gas related costs (related to 1559 transaction executed). // The use of nil here indicates that the gas price oracle should be relied on instead. - MsgGasFeeCap *big.Int `json:"gasFeeCap"` + GasFeeCap *big.Int `json:"gasFeeCap"` - // MsgGasTipCap represents the fee cap to use for 1559 transaction. The use of nil here indicates that the gas price + // GasTipCap represents the fee cap to use for 1559 transaction. The use of nil here indicates that the gas price // oracle should be relied on instead. - MsgGasTipCap *big.Int `json:"gasTipCap"` + GasTipCap *big.Int `json:"gasTipCap"` - // MsgData represents the underlying message data to be sent to the receiver. If the receiver is a smart contract, + // Data represents the underlying message data to be sent to the receiver. If the receiver is a smart contract, // this will likely house your call parameters and other serialized data. If MsgDataAbiValues is non-nil, this // value is not used. - MsgData []byte `json:"data,omitempty"` + Data []byte `json:"data,omitempty"` - // MsgDataAbiValues represents the underlying message data to be sent to the receiver. If the receiver is a smart - // contract, this will likely house your call parameters and other serialized data. This overrides MsgData if it is + // DataAbiValues represents the underlying message data to be sent to the receiver. If the receiver is a smart + // contract, this will likely house your call parameters and other serialized data. This overrides Data if it is // set, allowing Data to be sourced from method ABI input arguments instead. - MsgDataAbiValues *CallMessageDataAbiValues `json:"dataAbiValues,omitempty"` + DataAbiValues *CallMessageDataAbiValues `json:"dataAbiValues,omitempty"` + + // AccessList represents a core.Message's AccessList parameter which represents the storage slots and contracts + // that will be accessed during the execution of this message. + AccessList coreTypes.AccessList + + // SkipAccountChecks represents a core.Message's SkipAccountChecks. If it is set to true, then the message nonce + // is not checked against the account nonce in state and will not verify if the sender is an EOA. + SkipAccountChecks bool } // callMessageMarshaling is a structure that overrides field types during JSON marshaling. It allows CallMessage to // have its custom marshaling methods auto-generated and will handle type conversions for serialization purposes. // For example, this enables serialization of big.Int but specifying a different field type to control serialization. type callMessageMarshaling struct { - MsgValue *hexutil.Big - MsgGasPrice *hexutil.Big - MsgGasFeeCap *hexutil.Big - MsgGasTipCap *hexutil.Big - MsgData hexutil.Bytes + Value *hexutil.Big + GasPrice *hexutil.Big + GasFeeCap *hexutil.Big + GasTipCap *hexutil.Big + Data hexutil.Bytes } // NewCallMessage instantiates a new call message from a given set of parameters, with call data set from bytes. func NewCallMessage(from common.Address, to *common.Address, nonce uint64, value *big.Int, gasLimit uint64, gasPrice, gasFeeCap, gasTipCap *big.Int, data []byte) *CallMessage { // Construct and return a new message from our given parameters. return &CallMessage{ - MsgFrom: from, - MsgTo: to, - MsgNonce: nonce, - MsgValue: value, - MsgGas: gasLimit, - MsgGasPrice: gasPrice, - MsgGasFeeCap: gasFeeCap, - MsgGasTipCap: gasTipCap, - MsgData: data, - MsgDataAbiValues: nil, + From: from, + To: to, + Nonce: nonce, + Value: value, + GasLimit: gasLimit, + GasPrice: gasPrice, + GasFeeCap: gasFeeCap, + GasTipCap: gasTipCap, + Data: data, + DataAbiValues: nil, + AccessList: nil, + SkipAccountChecks: false, } } // NewCallMessageWithAbiValueData instantiates a new call message from a given set of parameters, with call data set // from method ABI specified inputs. -func NewCallMessageWithAbiValueData(from common.Address, to *common.Address, nonce uint64, value *big.Int, gasLimit uint64, gasPrice, gasFeeCap, gasTipCap *big.Int, data *CallMessageDataAbiValues) *CallMessage { +func NewCallMessageWithAbiValueData(from common.Address, to *common.Address, nonce uint64, value *big.Int, gasLimit uint64, gasPrice, gasFeeCap, gasTipCap *big.Int, abiData *CallMessageDataAbiValues) *CallMessage { + // Pack the ABI value data + var data []byte + var err error + if abiData != nil { + data, err = abiData.Pack() + if err != nil { + logging.GlobalLogger.Panic("Failed to pack call message ABI values", err) + } + } + // Construct and return a new message from our given parameters. return &CallMessage{ - MsgFrom: from, - MsgTo: to, - MsgNonce: nonce, - MsgValue: value, - MsgGas: gasLimit, - MsgGasPrice: gasPrice, - MsgGasFeeCap: gasFeeCap, - MsgGasTipCap: gasTipCap, - MsgData: nil, - MsgDataAbiValues: data, + From: from, + To: to, + Nonce: nonce, + Value: value, + GasLimit: gasLimit, + GasPrice: gasPrice, + GasFeeCap: gasFeeCap, + GasTipCap: gasTipCap, + Data: data, + DataAbiValues: abiData, + AccessList: nil, + SkipAccountChecks: false, } } @@ -107,68 +130,62 @@ func NewCallMessageWithAbiValueData(from common.Address, to *common.Address, non // underlying test chain properties if they are not yet set. func (m *CallMessage) FillFromTestChainProperties(chain *chain.TestChain) { // Set our nonce for this - m.MsgNonce = chain.State().GetNonce(m.MsgFrom) + m.Nonce = chain.State().GetNonce(m.From) // If a gas limit was not provided, allow the entire block gas limit to be used for this message. - if m.MsgGas == 0 { - m.MsgGas = chain.BlockGasLimit + if m.GasLimit == 0 { + m.GasLimit = chain.BlockGasLimit } // If a gas price was not provided, we use 1 as a default. - if m.MsgGasPrice == nil { - m.MsgGasPrice = big.NewInt(1) + if m.GasPrice == nil { + m.GasPrice = big.NewInt(1) } // Setting fee and tip cap to zero alongside the NoBaseFee for the vm.Config will bypass base fee validation. // TODO: Set this appropriately for newer transaction types. - m.MsgGasFeeCap = big.NewInt(0) - m.MsgGasTipCap = big.NewInt(0) + m.GasFeeCap = big.NewInt(0) + m.GasTipCap = big.NewInt(0) } -func (m *CallMessage) From() common.Address { return m.MsgFrom } -func (m *CallMessage) To() *common.Address { return m.MsgTo } -func (m *CallMessage) GasPrice() *big.Int { return m.MsgGasPrice } -func (m *CallMessage) GasFeeCap() *big.Int { return m.MsgGasFeeCap } -func (m *CallMessage) GasTipCap() *big.Int { return m.MsgGasTipCap } -func (m *CallMessage) Value() *big.Int { return m.MsgValue } -func (m *CallMessage) Gas() uint64 { return m.MsgGas } -func (m *CallMessage) Nonce() uint64 { return m.MsgNonce } -func (m *CallMessage) Data() []byte { - // If we have message data derived from ABI values, pack them and return the data. - if m.MsgDataAbiValues != nil { - data, err := m.MsgDataAbiValues.Pack() - if err != nil { - logging.GlobalLogger.Panic("Failed to pack call message ABI values", err) - } - return data - } - - // Otherwise we return our message data set from bytes. - return m.MsgData -} -func (m *CallMessage) AccessList() coreTypes.AccessList { return nil } -func (m *CallMessage) IsFake() bool { return true } - // Clone creates a copy of the given message and its underlying components, or an error if one occurs. func (m *CallMessage) Clone() (*CallMessage, error) { // Clone our underlying ABI values data if we have any. - clonedAbiValues, err := m.MsgDataAbiValues.Clone() + clonedAbiValues, err := m.DataAbiValues.Clone() if err != nil { return nil, err } // Create a message with the same data copied over. clone := &CallMessage{ - MsgFrom: m.MsgFrom, - MsgTo: m.MsgTo, // this value should be read-only, so we re-use it rather than cloning. - MsgNonce: m.MsgNonce, - MsgValue: new(big.Int).Set(m.MsgValue), - MsgGas: m.MsgGas, - MsgGasPrice: new(big.Int).Set(m.MsgGasPrice), - MsgGasFeeCap: new(big.Int).Set(m.MsgGasFeeCap), - MsgGasTipCap: new(big.Int).Set(m.MsgGasTipCap), - MsgData: slices.Clone(m.MsgData), - MsgDataAbiValues: clonedAbiValues, + From: m.From, + To: m.To, // this value should be read-only, so we re-use it rather than cloning. + Nonce: m.Nonce, + Value: new(big.Int).Set(m.Value), + GasLimit: m.GasLimit, + GasPrice: new(big.Int).Set(m.GasPrice), + GasFeeCap: new(big.Int).Set(m.GasFeeCap), + GasTipCap: new(big.Int).Set(m.GasTipCap), + Data: slices.Clone(m.Data), + DataAbiValues: clonedAbiValues, + AccessList: m.AccessList, + SkipAccountChecks: m.SkipAccountChecks, } return clone, nil } + +func (m *CallMessage) ToCoreMessage() *core.Message { + return &core.Message{ + To: m.To, + From: m.From, + Nonce: m.Nonce, + Value: new(big.Int).Set(m.Value), + GasLimit: m.GasLimit, + GasPrice: new(big.Int).Set(m.GasPrice), + GasFeeCap: new(big.Int).Set(m.GasFeeCap), + GasTipCap: new(big.Int).Set(m.GasTipCap), + Data: slices.Clone(m.Data), + AccessList: m.AccessList, + SkipAccountChecks: m.SkipAccountChecks, + } +} diff --git a/fuzzing/calls/call_sequence.go b/fuzzing/calls/call_sequence.go index 41ae2ccc..53ae874e 100644 --- a/fuzzing/calls/call_sequence.go +++ b/fuzzing/calls/call_sequence.go @@ -118,7 +118,7 @@ func (cs CallSequence) Hash() (common.Hash, error) { // Try to obtain a hash for the message/call. If this fails, we will replace it in the deferred panic // recovery. - messageHashData = utils.MessageToTransaction(cse.Call).Hash().Bytes() + messageHashData = utils.MessageToTransaction(cse.Call.ToCoreMessage()).Hash().Bytes() }() // Hash the message hash data. @@ -205,7 +205,7 @@ func (cse *CallSequenceElement) Method() (*abi.Method, error) { if cse.Contract == nil { return nil, nil } - return cse.Contract.CompiledContract().Abi.MethodById(cse.Call.Data()) + return cse.Contract.CompiledContract().Abi.MethodById(cse.Call.Data) } // String returns a displayable string representing the CallSequenceElement. @@ -224,7 +224,7 @@ func (cse *CallSequenceElement) String() string { } // Next decode our arguments (we jump four bytes to skip the function selector) - args, err := method.Inputs.Unpack(cse.Call.Data()[4:]) + args, err := method.Inputs.Unpack(cse.Call.Data[4:]) argsText := "" if err == nil { argsText, err = valuegeneration.EncodeABIArgumentsToString(method.Inputs, args) @@ -249,10 +249,10 @@ func (cse *CallSequenceElement) String() string { argsText, blockNumberStr, blockTimeStr, - cse.Call.Gas(), - cse.Call.GasPrice().String(), - cse.Call.Value().String(), - cse.Call.From(), + cse.Call.GasLimit, + cse.Call.GasPrice.String(), + cse.Call.Value.String(), + cse.Call.From, ) } @@ -273,7 +273,7 @@ func (cse *CallSequenceElement) AttachExecutionTrace(chain *chain.TestChain, con } // Perform our call with the given trace - _, cse.ExecutionTrace, err = executiontracer.CallWithExecutionTrace(chain, contractDefinitions, cse.Call, state) + _, cse.ExecutionTrace, err = executiontracer.CallWithExecutionTrace(chain, contractDefinitions, cse.Call.ToCoreMessage(), state) if err != nil { return fmt.Errorf("failed to resolve execution trace due to error replaying the call: %v", err) } diff --git a/fuzzing/calls/call_sequence_execution.go b/fuzzing/calls/call_sequence_execution.go index 8007bb6a..824c9c8e 100644 --- a/fuzzing/calls/call_sequence_execution.go +++ b/fuzzing/calls/call_sequence_execution.go @@ -84,7 +84,7 @@ func ExecuteCallSequenceIteratively(chain *chain.TestChain, fetchElementFunc Exe } // Try to add our transaction to this block. - err = chain.PendingBlockAddTx(callSequenceElement.Call) + err = chain.PendingBlockAddTx(callSequenceElement.Call.ToCoreMessage()) if err != nil { // If we encountered a block gas limit error, this tx is too expensive to fit in this block. // If there are other transactions in the block, this makes sense. The block is "full". diff --git a/fuzzing/calls/gen_call_message_json.go b/fuzzing/calls/gen_call_message_json.go index 5b3583bf..26662c91 100644 --- a/fuzzing/calls/gen_call_message_json.go +++ b/fuzzing/calls/gen_call_message_json.go @@ -8,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" ) var _ = (*callMessageMarshaling)(nil) @@ -15,78 +16,90 @@ var _ = (*callMessageMarshaling)(nil) // MarshalJSON marshals as JSON. func (c CallMessage) MarshalJSON() ([]byte, error) { type CallMessage struct { - MsgFrom common.Address `json:"from"` - MsgTo *common.Address `json:"to"` - MsgNonce uint64 `json:"nonce"` - MsgValue *hexutil.Big `json:"value"` - MsgGas uint64 `json:"gas"` - MsgGasPrice *hexutil.Big `json:"gasPrice"` - MsgGasFeeCap *hexutil.Big `json:"gasFeeCap"` - MsgGasTipCap *hexutil.Big `json:"gasTipCap"` - MsgData hexutil.Bytes `json:"data,omitempty"` - MsgDataAbiValues *CallMessageDataAbiValues `json:"dataAbiValues,omitempty"` + From common.Address `json:"from"` + To *common.Address `json:"to"` + Nonce uint64 `json:"nonce"` + Value *hexutil.Big `json:"value"` + GasLimit uint64 `json:"gasLimit"` + GasPrice *hexutil.Big `json:"gasPrice"` + GasFeeCap *hexutil.Big `json:"gasFeeCap"` + GasTipCap *hexutil.Big `json:"gasTipCap"` + Data hexutil.Bytes `json:"data,omitempty"` + DataAbiValues *CallMessageDataAbiValues `json:"dataAbiValues,omitempty"` + AccessList types.AccessList + SkipAccountChecks bool } var enc CallMessage - enc.MsgFrom = c.MsgFrom - enc.MsgTo = c.MsgTo - enc.MsgNonce = c.MsgNonce - enc.MsgValue = (*hexutil.Big)(c.MsgValue) - enc.MsgGas = c.MsgGas - enc.MsgGasPrice = (*hexutil.Big)(c.MsgGasPrice) - enc.MsgGasFeeCap = (*hexutil.Big)(c.MsgGasFeeCap) - enc.MsgGasTipCap = (*hexutil.Big)(c.MsgGasTipCap) - enc.MsgData = c.MsgData - enc.MsgDataAbiValues = c.MsgDataAbiValues + enc.From = c.From + enc.To = c.To + enc.Nonce = c.Nonce + enc.Value = (*hexutil.Big)(c.Value) + enc.GasLimit = c.GasLimit + enc.GasPrice = (*hexutil.Big)(c.GasPrice) + enc.GasFeeCap = (*hexutil.Big)(c.GasFeeCap) + enc.GasTipCap = (*hexutil.Big)(c.GasTipCap) + enc.Data = c.Data + enc.DataAbiValues = c.DataAbiValues + enc.AccessList = c.AccessList + enc.SkipAccountChecks = c.SkipAccountChecks return json.Marshal(&enc) } // UnmarshalJSON unmarshals from JSON. func (c *CallMessage) UnmarshalJSON(input []byte) error { type CallMessage struct { - MsgFrom *common.Address `json:"from"` - MsgTo *common.Address `json:"to"` - MsgNonce *uint64 `json:"nonce"` - MsgValue *hexutil.Big `json:"value"` - MsgGas *uint64 `json:"gas"` - MsgGasPrice *hexutil.Big `json:"gasPrice"` - MsgGasFeeCap *hexutil.Big `json:"gasFeeCap"` - MsgGasTipCap *hexutil.Big `json:"gasTipCap"` - MsgData *hexutil.Bytes `json:"data,omitempty"` - MsgDataAbiValues *CallMessageDataAbiValues `json:"dataAbiValues,omitempty"` + From *common.Address `json:"from"` + To *common.Address `json:"to"` + Nonce *uint64 `json:"nonce"` + Value *hexutil.Big `json:"value"` + GasLimit *uint64 `json:"gasLimit"` + GasPrice *hexutil.Big `json:"gasPrice"` + GasFeeCap *hexutil.Big `json:"gasFeeCap"` + GasTipCap *hexutil.Big `json:"gasTipCap"` + Data *hexutil.Bytes `json:"data,omitempty"` + DataAbiValues *CallMessageDataAbiValues `json:"dataAbiValues,omitempty"` + AccessList *types.AccessList + SkipAccountChecks *bool } var dec CallMessage if err := json.Unmarshal(input, &dec); err != nil { return err } - if dec.MsgFrom != nil { - c.MsgFrom = *dec.MsgFrom + if dec.From != nil { + c.From = *dec.From } - if dec.MsgTo != nil { - c.MsgTo = dec.MsgTo + if dec.To != nil { + c.To = dec.To } - if dec.MsgNonce != nil { - c.MsgNonce = *dec.MsgNonce + if dec.Nonce != nil { + c.Nonce = *dec.Nonce } - if dec.MsgValue != nil { - c.MsgValue = (*big.Int)(dec.MsgValue) + if dec.Value != nil { + c.Value = (*big.Int)(dec.Value) } - if dec.MsgGas != nil { - c.MsgGas = *dec.MsgGas + if dec.GasLimit != nil { + c.GasLimit = *dec.GasLimit } - if dec.MsgGasPrice != nil { - c.MsgGasPrice = (*big.Int)(dec.MsgGasPrice) + if dec.GasPrice != nil { + c.GasPrice = (*big.Int)(dec.GasPrice) } - if dec.MsgGasFeeCap != nil { - c.MsgGasFeeCap = (*big.Int)(dec.MsgGasFeeCap) + if dec.GasFeeCap != nil { + c.GasFeeCap = (*big.Int)(dec.GasFeeCap) } - if dec.MsgGasTipCap != nil { - c.MsgGasTipCap = (*big.Int)(dec.MsgGasTipCap) + if dec.GasTipCap != nil { + c.GasTipCap = (*big.Int)(dec.GasTipCap) } - if dec.MsgData != nil { - c.MsgData = *dec.MsgData + if dec.Data != nil { + c.Data = *dec.Data } - if dec.MsgDataAbiValues != nil { - c.MsgDataAbiValues = dec.MsgDataAbiValues + if dec.DataAbiValues != nil { + c.DataAbiValues = dec.DataAbiValues + } + if dec.AccessList != nil { + c.AccessList = *dec.AccessList + } + if dec.SkipAccountChecks != nil { + c.SkipAccountChecks = *dec.SkipAccountChecks } return nil } diff --git a/fuzzing/corpus/corpus.go b/fuzzing/corpus/corpus.go index d8c4d479..9cc4cda6 100644 --- a/fuzzing/corpus/corpus.go +++ b/fuzzing/corpus/corpus.go @@ -171,21 +171,21 @@ func (c *Corpus) initializeSequences(sequenceFiles *corpusDirectory[calls.CallSe // If we are deploying a contract and not targeting one with this call, there should be no work to do. currentSequenceElement := sequence[currentIndex] - if currentSequenceElement.Call.MsgTo == nil { + if currentSequenceElement.Call.To == nil { return currentSequenceElement, nil } // We are calling a contract with this call, ensure we can resolve the contract call is targeting. - resolvedContract, resolvedContractExists := deployedContracts[*currentSequenceElement.Call.MsgTo] + resolvedContract, resolvedContractExists := deployedContracts[*currentSequenceElement.Call.To] if !resolvedContractExists { - sequenceInvalidError = fmt.Errorf("contract at address '%v' could not be resolved", currentSequenceElement.Call.MsgTo.String()) + sequenceInvalidError = fmt.Errorf("contract at address '%v' could not be resolved", currentSequenceElement.Call.To.String()) return nil, nil } currentSequenceElement.Contract = resolvedContract // Next, if our sequence element uses ABI values to produce call data, our deserialized data is not yet // sufficient for runtime use, until we use it to resolve runtime references. - callAbiValues := currentSequenceElement.Call.MsgDataAbiValues + callAbiValues := currentSequenceElement.Call.DataAbiValues if callAbiValues != nil { sequenceInvalidError = callAbiValues.Resolve(currentSequenceElement.Contract.CompiledContract().Abi) if sequenceInvalidError != nil { diff --git a/fuzzing/corpus/corpus_test.go b/fuzzing/corpus/corpus_test.go index 3f32eefe..c49c904e 100644 --- a/fuzzing/corpus/corpus_test.go +++ b/fuzzing/corpus/corpus_test.go @@ -55,15 +55,15 @@ func getMockCallSequenceElement() *calls.CallSequenceElement { func getMockCallSequenceElementCall() *calls.CallMessage { to := common.BigToAddress(big.NewInt(rand.Int63())) txn := calls.CallMessage{ - MsgFrom: common.BigToAddress(big.NewInt(rand.Int63())), - MsgTo: &to, - MsgNonce: rand.Uint64(), - MsgValue: big.NewInt(int64(rand.Int())), - MsgGas: rand.Uint64(), - MsgGasPrice: big.NewInt(int64(rand.Int())), - MsgGasFeeCap: big.NewInt(int64(rand.Int())), - MsgGasTipCap: big.NewInt(int64(rand.Int())), - MsgData: []byte{uint8(rand.Uint64()), uint8(rand.Uint64()), uint8(rand.Uint64()), uint8(rand.Uint64())}, + From: common.BigToAddress(big.NewInt(rand.Int63())), + To: &to, + Nonce: rand.Uint64(), + Value: big.NewInt(int64(rand.Int())), + GasLimit: rand.Uint64(), + GasPrice: big.NewInt(int64(rand.Int())), + GasFeeCap: big.NewInt(int64(rand.Int())), + GasTipCap: big.NewInt(int64(rand.Int())), + Data: []byte{uint8(rand.Uint64()), uint8(rand.Uint64()), uint8(rand.Uint64()), uint8(rand.Uint64())}, } return &txn } diff --git a/fuzzing/executiontracer/execution_tracer.go b/fuzzing/executiontracer/execution_tracer.go index fdf6c08d..ed96dbe1 100644 --- a/fuzzing/executiontracer/execution_tracer.go +++ b/fuzzing/executiontracer/execution_tracer.go @@ -14,7 +14,7 @@ import ( // CallWithExecutionTrace obtains an execution trace for a given call, on the provided chain, using the state // provided. If a nil state is provided, the current chain state will be used. // Returns the ExecutionTrace for the call or an error if one occurs. -func CallWithExecutionTrace(chain *chain.TestChain, contractDefinitions contracts.Contracts, msg core.Message, state *state.StateDB) (*core.ExecutionResult, *ExecutionTrace, error) { +func CallWithExecutionTrace(chain *chain.TestChain, contractDefinitions contracts.Contracts, msg *core.Message, state *state.StateDB) (*core.ExecutionResult, *ExecutionTrace, error) { // Create an execution tracer executionTracer := NewExecutionTracer(contractDefinitions, chain.CheatCodeContracts()) diff --git a/fuzzing/fuzzer.go b/fuzzing/fuzzer.go index e64a7ba2..8c0269c1 100644 --- a/fuzzing/fuzzer.go +++ b/fuzzing/fuzzer.go @@ -376,7 +376,8 @@ func chainSetupFromCompilations(fuzzer *Fuzzer, testChain *chain.TestChain) erro } // Add our transaction to the block - err = testChain.PendingBlockAddTx(msg) + // Add our transaction to the block + err = testChain.PendingBlockAddTx(msg.ToCoreMessage()) if err != nil { return err } diff --git a/fuzzing/fuzzer_worker.go b/fuzzing/fuzzer_worker.go index f347c682..d8f01bed 100644 --- a/fuzzing/fuzzer_worker.go +++ b/fuzzing/fuzzer_worker.go @@ -323,6 +323,14 @@ func (fw *FuzzerWorker) testNextCallSequence() (calls.CallSequence, []ShrinkCall // shrink verifier. Chain state is reverted to the testing base prior to returning. // Returns a boolean indicating if the shrunken call sequence is valid for a given shrink request, or an error if one occurred. func (fw *FuzzerWorker) testShrunkenCallSequence(possibleShrunkSequence calls.CallSequence, shrinkRequest ShrinkCallSequenceRequest) (bool, error) { + // After testing the sequence, we'll want to rollback changes to reset our testing state. + var err error + defer func() { + if err == nil { + err = fw.chain.RevertToBlockNumber(fw.testingBaseBlockNumber) + } + }() + // Our "fetch next call method" method will simply fetch and fix the call message in case any fields are not correct due to shrinking. fetchElementFunc := func(currentIndex int) (*calls.CallSequenceElement, error) { // If we are at the end of our sequence, return nil indicating we should stop executing. @@ -340,9 +348,9 @@ func (fw *FuzzerWorker) testShrunkenCallSequence(possibleShrunkSequence calls.Ca executionCheckFunc := func(currentlyExecutedSequence calls.CallSequence) (bool, error) { // Check for updates to coverage and corpus (using only the section of the sequence we tested so far). // If we detect coverage changes, add this sequence. - err := fw.fuzzer.corpus.CheckSequenceCoverageAndUpdate(currentlyExecutedSequence, fw.getNewCorpusCallSequenceWeight(), true) - if err != nil { - return true, err + seqErr := fw.fuzzer.corpus.CheckSequenceCoverageAndUpdate(currentlyExecutedSequence, fw.getNewCorpusCallSequenceWeight(), true) + if seqErr != nil { + return true, seqErr } // If our fuzzer context is done, exit out immediately without results. @@ -354,7 +362,7 @@ func (fw *FuzzerWorker) testShrunkenCallSequence(possibleShrunkSequence calls.Ca } // Execute our call sequence. - _, err := calls.ExecuteCallSequenceIteratively(fw.chain, fetchElementFunc, executionCheckFunc) + _, err = calls.ExecuteCallSequenceIteratively(fw.chain, fetchElementFunc, executionCheckFunc) if err != nil { return false, err } @@ -372,11 +380,6 @@ func (fw *FuzzerWorker) testShrunkenCallSequence(possibleShrunkSequence calls.Ca return false, err } } - - // After testing the sequence, we'll want to rollback changes to reset our testing state. - if err = fw.chain.RevertToBlockNumber(fw.testingBaseBlockNumber); err != nil { - return false, err - } return validShrunkSequence, nil } @@ -430,7 +433,7 @@ func (fw *FuzzerWorker) shrinkCallSequence(callSequence calls.CallSequence, shri possibleShrunkSequence, _ := optimizedSequence.Clone() // Loop for each argument in the currently indexed call to mutate it. - abiValuesMsgData := possibleShrunkSequence[i].Call.MsgDataAbiValues + abiValuesMsgData := possibleShrunkSequence[i].Call.DataAbiValues for j := 0; j < len(abiValuesMsgData.InputValues); j++ { mutatedInput, err := valuegeneration.MutateAbiValue(fw.sequenceGenerator.config.ValueGenerator, fw.shrinkingValueMutator, &abiValuesMsgData.Method.Inputs[j].Type, abiValuesMsgData.InputValues[j]) if err != nil { diff --git a/fuzzing/fuzzer_worker_sequence_generator.go b/fuzzing/fuzzer_worker_sequence_generator.go index 8892cd3b..2b9358a4 100644 --- a/fuzzing/fuzzer_worker_sequence_generator.go +++ b/fuzzing/fuzzer_worker_sequence_generator.go @@ -260,6 +260,9 @@ func (g *CallSequenceGenerator) PopSequenceElement() (*calls.CallSequenceElement } } + // Update the element with the current nonce for the associated chain. + element.Call.FillFromTestChainProperties(g.worker.chain) + // Update our base sequence, advance our position, and return the processed element from this round. g.baseSequence[g.fetchIndex] = element g.fetchIndex++ @@ -301,7 +304,6 @@ func (g *CallSequenceGenerator) generateNewElement() (*calls.CallSequenceElement Method: &selectedMethod.Method, InputValues: args, }) - msg.FillFromTestChainProperties(g.worker.chain) // Determine our delay values for this element blockNumberDelay := uint64(0) @@ -441,12 +443,12 @@ func callSeqGenFuncInterleaveAtRandom(sequenceGenerator *CallSequenceGenerator, // Returns an error if one occurs. func prefetchModifyCallFuncMutate(sequenceGenerator *CallSequenceGenerator, element *calls.CallSequenceElement) error { // If this element has no ABI value based call data, exit early. - if element.Call == nil || element.Call.MsgDataAbiValues == nil { + if element.Call == nil || element.Call.DataAbiValues == nil { return nil } // Loop for each input value and mutate it - abiValuesMsgData := element.Call.MsgDataAbiValues + abiValuesMsgData := element.Call.DataAbiValues for i := 0; i < len(abiValuesMsgData.InputValues); i++ { mutatedInput, err := valuegeneration.MutateAbiValue(sequenceGenerator.config.ValueGenerator, sequenceGenerator.config.ValueMutator, &abiValuesMsgData.Method.Inputs[i].Type, abiValuesMsgData.InputValues[i]) if err != nil { diff --git a/fuzzing/test_case_optimization_provider.go b/fuzzing/test_case_optimization_provider.go index ba5ab258..424db7e5 100644 --- a/fuzzing/test_case_optimization_provider.go +++ b/fuzzing/test_case_optimization_provider.go @@ -96,10 +96,10 @@ func (t *OptimizationTestCaseProvider) runOptimizationTest(worker *FuzzerWorker, var executionTrace *executiontracer.ExecutionTrace if trace { executionTracer := executiontracer.NewExecutionTracer(worker.fuzzer.contractDefinitions, worker.chain.CheatCodeContracts()) - executionResult, err = worker.Chain().CallContract(msg, nil, executionTracer) + executionResult, err = worker.Chain().CallContract(msg.ToCoreMessage(), nil, executionTracer) executionTrace = executionTracer.Trace() } else { - executionResult, err = worker.Chain().CallContract(msg, nil) + executionResult, err = worker.Chain().CallContract(msg.ToCoreMessage(), nil) } if err != nil { return nil, nil, fmt.Errorf("failed to call optimization test method: %v", err) diff --git a/fuzzing/test_case_property_provider.go b/fuzzing/test_case_property_provider.go index ca8be15c..10399cc5 100644 --- a/fuzzing/test_case_property_provider.go +++ b/fuzzing/test_case_property_provider.go @@ -99,10 +99,10 @@ func (t *PropertyTestCaseProvider) checkPropertyTestFailed(worker *FuzzerWorker, var executionTrace *executiontracer.ExecutionTrace if trace { executionTracer := executiontracer.NewExecutionTracer(worker.fuzzer.contractDefinitions, worker.chain.CheatCodeContracts()) - executionResult, err = worker.Chain().CallContract(msg, nil, executionTracer) + executionResult, err = worker.Chain().CallContract(msg.ToCoreMessage(), nil, executionTracer) executionTrace = executionTracer.Trace() } else { - executionResult, err = worker.Chain().CallContract(msg, nil) + executionResult, err = worker.Chain().CallContract(msg.ToCoreMessage(), nil) } if err != nil { return false, nil, fmt.Errorf("failed to call property test method: %v", err) diff --git a/go.mod b/go.mod index ca1b0639..81250f0e 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.18 require ( github.com/Masterminds/semver v1.5.0 - github.com/ethereum/go-ethereum v1.11.1 + github.com/ethereum/go-ethereum v1.12.0 github.com/fxamacker/cbor v1.5.1 github.com/google/uuid v1.3.0 github.com/pkg/errors v0.9.1 @@ -15,6 +15,7 @@ require ( golang.org/x/crypto v0.11.0 golang.org/x/exp v0.0.0-20230206171751-46f607a40771 golang.org/x/net v0.12.0 + golang.org/x/sys v0.10.0 ) require ( @@ -33,13 +34,13 @@ require ( github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-stack/stack v1.8.1 // indirect + github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/golang/snappy v0.0.4 // indirect + github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/gorilla/websocket v1.5.0 // indirect - github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect - github.com/holiman/uint256 v1.2.1 // indirect + github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/klauspost/compress v1.15.15 // indirect github.com/kr/pretty v0.3.1 // indirect @@ -54,7 +55,6 @@ require ( github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect - github.com/prometheus/tsdb v0.10.0 // indirect github.com/rivo/uniseg v0.4.3 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect @@ -63,11 +63,10 @@ require ( github.com/tklauser/numcpus v0.6.0 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect - golang.org/x/sys v0.10.0 // indirect golang.org/x/text v0.11.0 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) -replace github.com/ethereum/go-ethereum v1.11.1 => github.com/crytic/medusa-geth v0.0.0-20230221190257-777a77b25150 +replace github.com/ethereum/go-ethereum => github.com/crytic/medusa-geth v0.0.0-20230811005223-cee04520a2f9 diff --git a/go.sum b/go.sum index fe8142b2..1db673f4 100644 --- a/go.sum +++ b/go.sum @@ -8,26 +8,20 @@ github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwS github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/VictoriaMetrics/fastcache v1.12.0 h1:vnVi/y9yKDcD9akmc4NqAoqgQhJrOwUF+j9LTgn4QDE= github.com/VictoriaMetrics/fastcache v1.12.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -52,8 +46,8 @@ github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1 github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/crytic/medusa-geth v0.0.0-20230221190257-777a77b25150 h1:Helt4ysP5N0cJzvhBsx4JcAOte5gD4whzamaXWpg37M= -github.com/crytic/medusa-geth v0.0.0-20230221190257-777a77b25150/go.mod h1:DuefStAgaxoaYGLR0FueVcVbehmn5n9QUcVrMCuOvuc= +github.com/crytic/medusa-geth v0.0.0-20230811005223-cee04520a2f9 h1:BUuL3h23IdVSmyq3I7LVUYRInKgXShMLKElYaFgn4RM= +github.com/crytic/medusa-geth v0.0.0-20230811005223-cee04520a2f9/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -64,9 +58,7 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -89,23 +81,19 @@ github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/ github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= -github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -127,9 +115,9 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -149,12 +137,10 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw= -github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e/go.mod h1:j9cQbcqHQujT0oKJ38PylVfqohClLr3CvDC+Qcg+lhU= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.2.1 h1:XRtyuda/zw2l+Bq/38n5XUoEF72aSOu/77Thd9pPp2o= -github.com/holiman/uint256 v1.2.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= +github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= @@ -169,7 +155,6 @@ github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrO github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= @@ -183,8 +168,6 @@ github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0 github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -193,6 +176,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -213,7 +197,6 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= @@ -225,14 +208,12 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -247,30 +228,20 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= -github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic= -github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -289,10 +260,8 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= @@ -304,7 +273,6 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -343,7 +311,6 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -368,7 +335,6 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -398,9 +364,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -486,7 +450,6 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -501,7 +464,6 @@ gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7 gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/utils/message_transaction_utils.go b/utils/message_transaction_utils.go index cfd54b25..57fd68ed 100644 --- a/utils/message_transaction_utils.go +++ b/utils/message_transaction_utils.go @@ -6,13 +6,13 @@ import ( ) // MessageToTransaction derives a types.Transaction from a types.Message. -func MessageToTransaction(msg core.Message) *types.Transaction { +func MessageToTransaction(msg *core.Message) *types.Transaction { return types.NewTx(&types.LegacyTx{ - Nonce: msg.Nonce(), - GasPrice: msg.GasPrice(), - Gas: msg.Gas(), - To: msg.To(), - Value: msg.Value(), - Data: msg.Data(), + Nonce: msg.Nonce, + GasPrice: msg.GasPrice, + Gas: msg.GasLimit, + To: msg.To, + Value: msg.Value, + Data: msg.Data, }) } From 4de61e80c823ea76fa0cd0f1f39448c5792c7c71 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Aug 2023 11:28:36 -0400 Subject: [PATCH 3/4] Bump golang.org/x/net from 0.12.0 to 0.14.0 (#196) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.12.0 to 0.14.0. - [Commits](https://github.com/golang/net/compare/v0.12.0...v0.14.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 81250f0e..1aec9600 100644 --- a/go.mod +++ b/go.mod @@ -12,10 +12,10 @@ require ( github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.4 - golang.org/x/crypto v0.11.0 + golang.org/x/crypto v0.12.0 golang.org/x/exp v0.0.0-20230206171751-46f607a40771 - golang.org/x/net v0.12.0 - golang.org/x/sys v0.10.0 + golang.org/x/net v0.14.0 + golang.org/x/sys v0.11.0 ) require ( @@ -63,7 +63,7 @@ require ( github.com/tklauser/numcpus v0.6.0 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect - golang.org/x/text v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 1db673f4..1c621d8b 100644 --- a/go.sum +++ b/go.sum @@ -319,8 +319,8 @@ golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20230206171751-46f607a40771 h1:xP7rWLUr1e1n2xkK5YB4LI0hPEy3LJC6Wk+D4pGlOJg= golang.org/x/exp v0.0.0-20230206171751-46f607a40771/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= @@ -351,8 +351,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -394,8 +394,8 @@ golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -403,8 +403,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= From 7d2e16caeff98133e4c763c6ceb04abc1af674dd Mon Sep 17 00:00:00 2001 From: anishnaik Date: Tue, 15 Aug 2023 15:54:16 -0400 Subject: [PATCH 4/4] `console.log` go brrr (#193) Introduce `console.log` functionality with string formatting capabilities. --------- Co-authored-by: David Pokora --- chain/cheat_code_contract.go | 27 +- chain/console_log_cheat_code_contract.go | 124 ++ ...des.go => standard_cheat_code_contract.go} | 24 +- compilation/abiutils/solidity_errors.go | 20 +- fuzzing/executiontracer/execution_trace.go | 77 +- fuzzing/fuzzer_test.go | 56 +- .../cheat_codes/console_log/console_log.sol | 1568 +++++++++++++++++ logging/colors/constants.go | 3 + utils/combinatorial_utils.go | 46 + 9 files changed, 1898 insertions(+), 47 deletions(-) create mode 100644 chain/console_log_cheat_code_contract.go rename chain/{cheat_codes.go => standard_cheat_code_contract.go} (94%) create mode 100644 fuzzing/testdata/contracts/cheat_codes/console_log/console_log.sol create mode 100644 utils/combinatorial_utils.go diff --git a/chain/cheat_code_contract.go b/chain/cheat_code_contract.go index 0b644cfc..08ceb6ea 100644 --- a/chain/cheat_code_contract.go +++ b/chain/cheat_code_contract.go @@ -54,6 +54,30 @@ type cheatCodeRawReturnData struct { Err error } +// getCheatCodeProviders obtains a cheatCodeTracer (used to power cheat code analysis) and associated CheatCodeContract +// objects linked to the tracer (providing on-chain callable methods as an entry point). These objects are attached to +// the TestChain to enable cheat code functionality. +// Returns the tracer and associated pre-compile contracts, or an error, if one occurred. +func getCheatCodeProviders() (*cheatCodeTracer, []*CheatCodeContract, error) { + // Create a cheat code tracer and attach it to the chain. + tracer := newCheatCodeTracer() + + // Obtain our standard cheat code pre-compile + stdCheatCodeContract, err := getStandardCheatCodeContract(tracer) + if err != nil { + return nil, nil, err + } + + // Obtain the console.log pre-compile + consoleCheatCodeContract, err := getConsoleLogCheatCodeContract(tracer) + if err != nil { + return nil, nil, err + } + + // Return the tracer and precompiles + return tracer, []*CheatCodeContract{stdCheatCodeContract, consoleCheatCodeContract}, nil +} + // newCheatCodeContract returns a new precompiledContract which uses the attached cheatCodeTracer for execution // context. func newCheatCodeContract(tracer *cheatCodeTracer, address common.Address, name string) *CheatCodeContract { @@ -98,7 +122,7 @@ func (c *CheatCodeContract) Abi() *abi.ABI { } // addMethod adds a new method to the precompiled contract. -// Returns an error if one occurred. +// Throws a panic if either the name is the empty string or the handler is nil. func (c *CheatCodeContract) addMethod(name string, inputs abi.Arguments, outputs abi.Arguments, handler cheatCodeMethodHandler) { // Verify a method name was provided if name == "" { @@ -117,7 +141,6 @@ func (c *CheatCodeContract) addMethod(name string, inputs abi.Arguments, outputs method: method, handler: handler, } - // Add the method to the ABI. // Note: Normally the key here should be the method name, not sig. But cheat code contracts have duplicate // method names with different parameter types, so we use this so they don't override. diff --git a/chain/console_log_cheat_code_contract.go b/chain/console_log_cheat_code_contract.go new file mode 100644 index 00000000..1c20dedb --- /dev/null +++ b/chain/console_log_cheat_code_contract.go @@ -0,0 +1,124 @@ +package chain + +import ( + "github.com/crytic/medusa/utils" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "strconv" +) + +// ConsoleLogContractAddress is the address for the console.log precompile contract +var ConsoleLogContractAddress = common.HexToAddress("0x000000000000000000636F6e736F6c652e6c6f67") + +// getConsoleLogCheatCodeContract obtains a CheatCodeContract which implements the console.log functions. +// Returns the precompiled contract, or an error if there is one. +func getConsoleLogCheatCodeContract(tracer *cheatCodeTracer) (*CheatCodeContract, error) { + // Create a new precompile to add methods to. + contract := newCheatCodeContract(tracer, ConsoleLogContractAddress, "Console") + + // Define all the ABI types needed for console.log functions + typeUint256, err := abi.NewType("uint256", "", nil) + if err != nil { + return nil, err + } + typeInt256, err := abi.NewType("int256", "", nil) + if err != nil { + return nil, err + } + typeString, err := abi.NewType("string", "", nil) + if err != nil { + return nil, err + } + typeBool, err := abi.NewType("bool", "", nil) + if err != nil { + return nil, err + } + typeAddress, err := abi.NewType("address", "", nil) + if err != nil { + return nil, err + } + typeBytes, err := abi.NewType("bytes", "", nil) + if err != nil { + return nil, err + } + + // We will store all the fixed byte (e.g. byte1, byte2) in a mapping + const numFixedByteTypes = 32 + fixedByteTypes := make(map[int]abi.Type, numFixedByteTypes) + for i := 1; i <= numFixedByteTypes; i++ { + byteString := "bytes" + strconv.FormatInt(int64(i), 10) + fixedByteTypes[i], err = abi.NewType(byteString, "", nil) + if err != nil { + return nil, err + } + } + + // We have a few special log function signatures outside all the permutations of (string, uint256, bool, address). + // These include log(int256), log(bytes), log(bytesX), and log(string, uint256). So, we will manually create these + // signatures and then programmatically iterate through all the permutations. + + // Note that none of the functions actually do anything - they just have to be callable so that the execution + // traces can show the arguments that the user wants to log! + + // log(int256): Log an int256 + contract.addMethod("log", abi.Arguments{{Type: typeInt256}}, abi.Arguments{}, + func(tracer *cheatCodeTracer, inputs []any) ([]any, *cheatCodeRawReturnData) { + return nil, nil + }, + ) + + // log(bytes): Log bytes + contract.addMethod("log", abi.Arguments{{Type: typeBytes}}, abi.Arguments{}, + func(tracer *cheatCodeTracer, inputs []any) ([]any, *cheatCodeRawReturnData) { + return nil, nil + }, + ) + + // Now, we will add the logBytes1, logBytes2, and so on in a loop + for i := 1; i <= numFixedByteTypes; i++ { + // Create local copy of abi argument + fixedByteType := fixedByteTypes[i] + + // Add the method + contract.addMethod("log", abi.Arguments{{Type: fixedByteType}}, abi.Arguments{}, + func(tracer *cheatCodeTracer, inputs []any) ([]any, *cheatCodeRawReturnData) { + return nil, nil + }, + ) + } + + // log(string, int256): Log string with an int where the string could be formatted + contract.addMethod("log", abi.Arguments{{Type: typeString}, {Type: typeInt256}}, abi.Arguments{}, + func(tracer *cheatCodeTracer, inputs []any) ([]any, *cheatCodeRawReturnData) { + return nil, nil + }, + ) + + // These are the four parameter types that console.log() accepts + choices := abi.Arguments{{Type: typeUint256}, {Type: typeString}, {Type: typeBool}, {Type: typeAddress}} + + // Create all possible permutations (with repetition) where the number of choices increases from 1...len(choices) + permutations := make([]abi.Arguments, 0) + for n := 1; n <= len(choices); n++ { + nextSetOfPermutations := utils.PermutationsWithRepetition(choices, n) + for _, permutation := range nextSetOfPermutations { + permutations = append(permutations, permutation) + } + } + + // Iterate across each permutation to add their associated event and function handler + for i := 0; i < len(permutations); i++ { + // Make a local copy of the current permutation + permutation := permutations[i] + + // Create the function handler + contract.addMethod("log", permutation, abi.Arguments{}, + func(tracer *cheatCodeTracer, inputs []any) ([]any, *cheatCodeRawReturnData) { + return nil, nil + }, + ) + } + + // Return our precompile contract information. + return contract, nil +} diff --git a/chain/cheat_codes.go b/chain/standard_cheat_code_contract.go similarity index 94% rename from chain/cheat_codes.go rename to chain/standard_cheat_code_contract.go index 49bd4ae3..141bf204 100644 --- a/chain/cheat_codes.go +++ b/chain/standard_cheat_code_contract.go @@ -14,30 +14,14 @@ import ( "strings" ) -// getCheatCodeProviders obtains a cheatCodeTracer (used to power cheat code analysis) and associated CheatCodeContract -// objects linked to the tracer (providing on-chain callable methods as an entry point). These objects are attached to -// the TestChain to enable cheat code functionality. -// Returns the tracer and associated pre-compile contracts, or an error, if one occurred. -func getCheatCodeProviders() (*cheatCodeTracer, []*CheatCodeContract, error) { - // Create a cheat code tracer and attach it to the chain. - tracer := newCheatCodeTracer() - - // Obtain our cheat code pre-compiles - stdCheatCodeContract, err := getStandardCheatCodeContract(tracer) - if err != nil { - return nil, nil, err - } - - // Return the tracer and precompiles - return tracer, []*CheatCodeContract{stdCheatCodeContract}, nil -} +// StandardCheatcodeContractAddress is the address for the standard cheatcode contract +var StandardCheatcodeContractAddress = common.HexToAddress("0x7109709ECfa91a80626fF3989D68f67F5b1DD12D") // getStandardCheatCodeContract obtains a CheatCodeContract which implements common cheat codes. // Returns the precompiled contract, or an error if one occurs. func getStandardCheatCodeContract(tracer *cheatCodeTracer) (*CheatCodeContract, error) { - // Define our address for this precompile contract, then create a new precompile to add methods to. - contractAddress := common.HexToAddress("0x7109709ECfa91a80626fF3989D68f67F5b1DD12D") - contract := newCheatCodeContract(tracer, contractAddress, "StdCheats") + // Create a new precompile to add methods to. + contract := newCheatCodeContract(tracer, StandardCheatcodeContractAddress, "StdCheats") // Define some basic ABI argument types typeAddress, err := abi.NewType("address", "", nil) diff --git a/compilation/abiutils/solidity_errors.go b/compilation/abiutils/solidity_errors.go index 384a8fda..fd848f99 100644 --- a/compilation/abiutils/solidity_errors.go +++ b/compilation/abiutils/solidity_errors.go @@ -113,25 +113,25 @@ func GetPanicReason(panicCode uint64) string { // Switch on panic code switch panicCode { case PanicCodeCompilerInserted: - return "compiler inserted panic" + return "panic: compiler inserted panic" case PanicCodeAssertFailed: - return "assertion failed" + return "panic: assertion failed" case PanicCodeArithmeticUnderOverflow: - return "arithmetic underflow" + return "panic: arithmetic underflow" case PanicCodeDivideByZero: - return "division by zero" + return "panic: division by zero" case PanicCodeEnumTypeConversionOutOfBounds: - return "enum access out of bounds" + return "panic: enum access out of bounds" case PanicCodeIncorrectStorageAccess: - return "incorrect storage access" + return "panic: incorrect storage access" case PanicCodePopEmptyArray: - return "pop on empty array" + return "panic: pop on empty array" case PanicCodeOutOfBoundsArrayAccess: - return "out of bounds array access" + return "panic: out of bounds array access" case PanicCodeAllocateTooMuchMemory: - return "overallocation of memory" + return "panic; overallocation of memory" case PanicCodeCallUninitializedVariable: - return "call on uninitialized variable" + return "panic: call on uninitialized variable" default: return fmt.Sprintf("unknown panic code(%v)", panicCode) } diff --git a/fuzzing/executiontracer/execution_trace.go b/fuzzing/executiontracer/execution_trace.go index a021de9d..287ce52c 100644 --- a/fuzzing/executiontracer/execution_trace.go +++ b/fuzzing/executiontracer/execution_trace.go @@ -3,6 +3,7 @@ package executiontracer import ( "encoding/hex" "fmt" + "github.com/crytic/medusa/chain" "github.com/crytic/medusa/compilation/abiutils" "github.com/crytic/medusa/fuzzing/contracts" "github.com/crytic/medusa/fuzzing/valuegeneration" @@ -11,6 +12,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" coreTypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "regexp" "strings" ) @@ -36,10 +38,12 @@ func newExecutionTrace(contracts contracts.Contracts) *ExecutionTrace { // generateCallFrameEnterElements generates a list of elements describing top level information about this call frame. // This list of elements will hold information about what kind of call it is, wei sent, what method is called, and more. -// Additionally, the list may also hold formatting options for console output. -func (t *ExecutionTrace) generateCallFrameEnterElements(callFrame *CallFrame) []any { - // Create list of elements +// Additionally, the list may also hold formatting options for console output. This function also returns a non-empty +// string in case this call frame represents a call to the console.log precompile contract. +func (t *ExecutionTrace) generateCallFrameEnterElements(callFrame *CallFrame) ([]any, string) { + // Create list of elements and console log string elements := make([]any, 0) + var consoleLogString string // Define some strings and objects that represent our current call frame var ( @@ -95,10 +99,30 @@ func (t *ExecutionTrace) generateCallFrameEnterElements(callFrame *CallFrame) [] // Unpack our input values and obtain a string to represent them inputValues, err := method.Inputs.Unpack(abiDataInputBuffer) if err == nil { + // Encode the ABI arguments into strings encodedInputString, err := valuegeneration.EncodeABIArgumentsToString(method.Inputs, inputValues) if err == nil { inputArgumentsDisplayText = &encodedInputString } + + // If the call was made to the console log precompile address, let's retrieve the log and format it + if callFrame.ToAddress == chain.ConsoleLogContractAddress { + // First, attempt to do string formatting if the first element is a string and has a percent sign in it + exp := regexp.MustCompile(`%`) + stringInput, isString := inputValues[0].(string) + if isString && exp.MatchString(stringInput) { + // Format the string and add it to the list of logs + consoleLogString = fmt.Sprintf(inputValues[0].(string), inputValues[1:]...) + } else { + // The string does not need to be formatted, and we can just use the encoded input string + consoleLogString = encodedInputString + } + + // Add a bullet point before the string and a new line after the string + if len(consoleLogString) > 0 { + consoleLogString = colors.BULLET_POINT + " " + consoleLogString + "\n" + } + } } } @@ -120,7 +144,11 @@ func (t *ExecutionTrace) generateCallFrameEnterElements(callFrame *CallFrame) [] } } else { if callFrame.ExecutedCode { - callInfo = fmt.Sprintf("%v.%v(%v) (addr=%v, value=%v, sender=%v)", codeContractName, methodName, *inputArgumentsDisplayText, callFrame.ToAddress.String(), callFrame.CallValue, callFrame.SenderAddress.String()) + if callFrame.ToAddress == chain.ConsoleLogContractAddress { + callInfo = fmt.Sprintf("%v.%v(%v)", codeContractName, methodName, *inputArgumentsDisplayText) + } else { + callInfo = fmt.Sprintf("%v.%v(%v) (addr=%v, value=%v, sender=%v)", codeContractName, methodName, *inputArgumentsDisplayText, callFrame.ToAddress.String(), callFrame.CallValue, callFrame.SenderAddress.String()) + } } else { callInfo = fmt.Sprintf("(addr=%v, value=%v, sender=%v)", callFrame.ToAddress.String(), callFrame.CallValue, callFrame.SenderAddress.String()) } @@ -129,7 +157,7 @@ func (t *ExecutionTrace) generateCallFrameEnterElements(callFrame *CallFrame) [] // Add call information to the elements elements = append(elements, callInfo, "\n") - return elements + return elements, consoleLogString } // generateCallFrameExitElements generates a list of elements describing the return data of the call frame (e.g. @@ -263,11 +291,13 @@ func (t *ExecutionTrace) generateEventEmittedElements(callFrame *CallFrame, even return elements } -// generateElementsForCallFrame generates a list of elements for a given call frame and its children. Additionally, -// the list may also hold formatting options for console output. -func (t *ExecutionTrace) generateElementsForCallFrame(currentDepth int, callFrame *CallFrame) []any { - // Create list of elements +// generateElementsAndLogsForCallFrame generates a list of elements and logs for a given call frame and its children. +// The list of elements may also hold formatting options for console output. The list of logs represent calls to the +// console.log precompile contract. +func (t *ExecutionTrace) generateElementsAndLogsForCallFrame(currentDepth int, callFrame *CallFrame) ([]any, []any) { + // Create list of elements and logs elements := make([]any, 0) + consoleLogs := make([]any, 0) // Create our current call line prefix (indented by call depth) prefix := strings.Repeat("\t", currentDepth) + " => " @@ -278,8 +308,14 @@ func (t *ExecutionTrace) generateElementsForCallFrame(currentDepth int, callFram } // Add the call frame enter header elements + newElements, consoleLogString := t.generateCallFrameEnterElements(callFrame) elements = append(elements, prefix) - elements = append(elements, t.generateCallFrameEnterElements(callFrame)...) + elements = append(elements, newElements...) + + // If this call frame was a console.log contract call, add the string to the list of logs + if len(consoleLogString) > 0 { + consoleLogs = append(consoleLogs, consoleLogString) + } // Now that the header has been printed, create our indent level to express everything that // happened under it. @@ -293,8 +329,9 @@ func (t *ExecutionTrace) generateElementsForCallFrame(currentDepth int, callFram for _, operation := range callFrame.Operations { if childCallFrame, ok := operation.(*CallFrame); ok { // If this is a call frame being entered, generate information recursively. - childOutputLines := t.generateElementsForCallFrame(currentDepth+1, childCallFrame) + childOutputLines, childConsoleLogStrings := t.generateElementsAndLogsForCallFrame(currentDepth+1, childCallFrame) elements = append(elements, childOutputLines...) + consoleLogs = append(consoleLogs, childConsoleLogStrings...) } else if eventLog, ok := operation.(*coreTypes.Log); ok { // If an event log was emitted, add a message for it. elements = append(elements, prefix) @@ -304,23 +341,35 @@ func (t *ExecutionTrace) generateElementsForCallFrame(currentDepth int, callFram // If we self-destructed, add a message for it before our footer. if callFrame.SelfDestructed { - elements = append(elements, prefix, colors.MagentaBold, "[selfdestruct]", colors.Reset, "\n") + elements = append(elements, prefix, colors.RedBold, "[selfdestruct]", colors.Reset, "\n") } // Add the call frame exit footer elements = append(elements, prefix) elements = append(elements, t.generateCallFrameExitElements(callFrame)...) + } // Return our elements - return elements + return elements, consoleLogs } // Log returns a logging.LogBuffer that represents this execution trace. This buffer will be passed to the underlying // logger which will format it accordingly for console or file. func (t *ExecutionTrace) Log() *logging.LogBuffer { + // Create a buffer buffer := logging.NewLogBuffer() - buffer.Append(t.generateElementsForCallFrame(0, t.TopLevelCallFrame)...) + + // First, add the elements that make up the overarching execution trace + elements, logs := t.generateElementsAndLogsForCallFrame(0, t.TopLevelCallFrame) + buffer.Append(elements...) + + // If we captured any logs during tracing, add them to the overarching execution trace + if len(logs) > 0 { + buffer.Append(colors.Bold, "[Logs]", colors.Reset, "\n") + buffer.Append(logs...) + } + return buffer } diff --git a/fuzzing/fuzzer_test.go b/fuzzing/fuzzer_test.go index 42ff13c5..978ecbc0 100644 --- a/fuzzing/fuzzer_test.go +++ b/fuzzing/fuzzer_test.go @@ -258,6 +258,60 @@ func TestCheatCodes(t *testing.T) { } } +// TestConsoleLog tests the console.log precompile contract by logging a variety of different primitive types and +// then failing. The execution trace for the failing call sequence should hold the various logs. +func TestConsoleLog(t *testing.T) { + // These are the logs that should show up in the execution trace + expectedLogs := []string{ + "2", + "hello world", + "byte", + "i is 2", + "% bool is true, addr is 0x0000000000000000000000000000000000000000, u is 100", + } + + filePaths := []string{ + "testdata/contracts/cheat_codes/console_log/console_log.sol", + } + for _, filePath := range filePaths { + runFuzzerTest(t, &fuzzerSolcFileTest{ + filePath: filePath, + configUpdates: func(config *config.ProjectConfig) { + config.Fuzzing.DeploymentOrder = []string{"TestContract"} + config.Fuzzing.TestLimit = 10000 + // enable assertion testing only + config.Fuzzing.Testing.PropertyTesting.Enabled = true + config.Fuzzing.Testing.AssertionTesting.Enabled = true + }, + method: func(f *fuzzerTestContext) { + // Start the fuzzer + err := f.fuzzer.Start() + assert.NoError(t, err) + + // Check for failed assertion tests. + failedTestCase := f.fuzzer.TestCasesWithStatus(TestCaseStatusFailed) + assert.NotEmpty(t, failedTestCase, "expected to have failed test cases") + + // Obtain our first failed test case, get the message, and verify it contains our assertion failed. + failingSequence := *failedTestCase[0].CallSequence() + assert.NotEmpty(t, failingSequence, "expected to have calls in the call sequence failing an assertion test") + + // Obtain the last call + lastCall := failingSequence[len(failingSequence)-1] + assert.NotNilf(t, lastCall.ExecutionTrace, "expected to have an execution trace attached to call sequence for this test") + + // Get the execution trace message + executionTraceMsg := lastCall.ExecutionTrace.Log().String() + + // Verify it contains all expected logs + for _, expectedLog := range expectedLogs { + assert.Contains(t, executionTraceMsg, expectedLog) + } + }, + }) + } +} + // TestDeploymentsInnerDeployments runs tests to ensure dynamically deployed contracts are detected by the Fuzzer and // their properties are tested appropriately. func TestDeploymentsInnerDeployments(t *testing.T) { @@ -379,7 +433,7 @@ func TestExecutionTraces(t *testing.T) { "testdata/contracts/execution_tracing/proxy_call.sol": {"TestContract -> InnerDeploymentContract.setXY", "Hello from proxy call args!"}, "testdata/contracts/execution_tracing/revert_custom_error.sol": {"CustomError", "Hello from a custom error!"}, "testdata/contracts/execution_tracing/revert_reasons.sol": {"RevertingContract was called and reverted."}, - "testdata/contracts/execution_tracing/self_destruct.sol": {"[selfdestruct]", "[assertion failed]"}, + "testdata/contracts/execution_tracing/self_destruct.sol": {"[selfdestruct]", "[panic: assertion failed]"}, } for filePath, expectedTraceMessages := range expectedMessagesPerTest { runFuzzerTest(t, &fuzzerSolcFileTest{ diff --git a/fuzzing/testdata/contracts/cheat_codes/console_log/console_log.sol b/fuzzing/testdata/contracts/cheat_codes/console_log/console_log.sol new file mode 100644 index 00000000..ddf5ffe4 --- /dev/null +++ b/fuzzing/testdata/contracts/cheat_codes/console_log/console_log.sol @@ -0,0 +1,1568 @@ +// Test console.log capabilities to make sure logging and string formatting are happening as expected +contract TestContract { + + function testConsoleLog() public { + // Log an int256 + int256 i = 2; + console.log(i); + + // Log bytes + bytes memory byteSlice = "hello world"; + console.logBytes(byteSlice); + + // Log fixed bytes + bytes4 fixedBytes = "byte"; + console.logBytes4(fixedBytes); + + // Log a string and int256 while testing string formatting + string memory str = "i is %d"; + console.log(str, i); + + // Test the permutation logic by logging a random permutation and also string formatting + bool b = true; + address addr = address(0); + uint256 u = 100; + str = "%% bool is %t, addr is %s, u is %d"; + console.log(str, b, addr, u); + assert(false); + } +} + +library console { + address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); + + function _sendLogPayload(bytes memory payload) private view { + uint256 payloadLength = payload.length; + address consoleAddress = CONSOLE_ADDRESS; + /// @solidity memory-safe-assembly + assembly { + let payloadStart := add(payload, 32) + let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) + } + } + + function log() internal view { + _sendLogPayload(abi.encodeWithSignature("log()")); + } + + function logInt(int256 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); + } + + function logUint(uint256 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); + } + + function logString(string memory p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); + } + + function logBool(bool p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); + } + + function logAddress(address p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); + } + + function logBytes(bytes memory p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); + } + + function logBytes1(bytes1 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); + } + + function logBytes2(bytes2 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); + } + + function logBytes3(bytes3 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); + } + + function logBytes4(bytes4 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); + } + + function logBytes5(bytes5 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); + } + + function logBytes6(bytes6 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); + } + + function logBytes7(bytes7 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); + } + + function logBytes8(bytes8 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); + } + + function logBytes9(bytes9 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); + } + + function logBytes10(bytes10 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); + } + + function logBytes11(bytes11 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); + } + + function logBytes12(bytes12 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); + } + + function logBytes13(bytes13 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); + } + + function logBytes14(bytes14 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); + } + + function logBytes15(bytes15 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); + } + + function logBytes16(bytes16 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); + } + + function logBytes17(bytes17 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); + } + + function logBytes18(bytes18 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); + } + + function logBytes19(bytes19 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); + } + + function logBytes20(bytes20 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); + } + + function logBytes21(bytes21 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); + } + + function logBytes22(bytes22 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); + } + + function logBytes23(bytes23 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); + } + + function logBytes24(bytes24 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); + } + + function logBytes25(bytes25 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); + } + + function logBytes26(bytes26 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); + } + + function logBytes27(bytes27 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); + } + + function logBytes28(bytes28 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); + } + + function logBytes29(bytes29 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); + } + + function logBytes30(bytes30 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); + } + + function logBytes31(bytes31 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); + } + + function logBytes32(bytes32 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); + } + + function log(uint256 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); + } + + function log(int256 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); + } + + function log(string memory p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); + } + + function log(bool p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); + } + + function log(address p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); + } + + function log(uint256 p0, uint256 p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1)); + } + + function log(uint256 p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1)); + } + + function log(uint256 p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1)); + } + + function log(uint256 p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1)); + } + + function log(string memory p0, uint256 p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); + } + + function log(string memory p0, int256 p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,int256)", p0, p1)); + } + + function log(string memory p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); + } + + function log(string memory p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); + } + + function log(string memory p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); + } + + function log(bool p0, uint256 p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1)); + } + + function log(bool p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); + } + + function log(bool p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); + } + + function log(bool p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); + } + + function log(address p0, uint256 p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1)); + } + + function log(address p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); + } + + function log(address p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); + } + + function log(address p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); + } + + function log(uint256 p0, uint256 p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); + } + + function log(string memory p0, address p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2)); + } + + function log(string memory p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); + } + + function log(string memory p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); + } + + function log(string memory p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); + } + + function log(bool p0, bool p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2)); + } + + function log(bool p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); + } + + function log(bool p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); + } + + function log(bool p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); + } + + function log(bool p0, address p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2)); + } + + function log(bool p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); + } + + function log(bool p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); + } + + function log(bool p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2)); + } + + function log(address p0, string memory p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2)); + } + + function log(address p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); + } + + function log(address p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); + } + + function log(address p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); + } + + function log(address p0, bool p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2)); + } + + function log(address p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); + } + + function log(address p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); + } + + function log(address p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); + } + + function log(address p0, address p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2)); + } + + function log(address p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); + } + + function log(address p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); + } + + function log(address p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); + } + +} \ No newline at end of file diff --git a/logging/colors/constants.go b/logging/colors/constants.go index c1a7657a..4f3f555a 100644 --- a/logging/colors/constants.go +++ b/logging/colors/constants.go @@ -31,4 +31,7 @@ const ( const ( // LEFT_ARROW is the unicode string for a left arrow glyph LEFT_ARROW = "\u21fe" + + // BULLET_POINT is the unicode string for a triangular bullet point + BULLET_POINT = "\u2023" ) diff --git a/utils/combinatorial_utils.go b/utils/combinatorial_utils.go new file mode 100644 index 00000000..7eea59d4 --- /dev/null +++ b/utils/combinatorial_utils.go @@ -0,0 +1,46 @@ +package utils + +// PermutationsWithRepetition will take in an array and an integer, n, where n represents how many items need to +// be selected from the array. The function returns an array of all permutations of size n +func PermutationsWithRepetition[T any](choices []T, n int) [][]T { + numChoices := len(choices) + + // At each iteration of the for loop below, one of the indices in counter + // increments by one. Here is what selector looks like over a few iterations + // [0, 0, 0, 0] -> [1, 0, 0, 0] -> ... -> [2, 1, 0, 0] -> ... -> [4, 3, 1, 0] and so on until we reach back to + // [0, 0, 0, 0] which means all permutations have been enumerated. + counter := make([]int, n) + permutations := make([][]T, 0) + for { + // The counter will determine the order of the current permutation. The i-th value of the permutation is equal to + // the x-th index in the choices array. + permutation := make([]T, n) + for i, x := range counter { + permutation[i] = choices[x] + } + + // Add the permutation to the list of permutations + permutations = append(permutations, permutation) + + // This for loop will determine the next value of the counter array + for i := 0; ; { + // Increment the i-th index + counter[i]++ + // If we haven't updated the i-th index of counter up to numChoices - 1, we increment that index + if counter[i] < numChoices { + break + } + + // Once the i-th index is equal to numChoices, we reset counter[i] back to 0 and move on to the next index + // with i++ + counter[i] = 0 + i++ + + // Once we reach the length of the counter array, we are done with enumerating all permutations since all + // indices in the counter array have been reset back to 0 + if i == n { + return permutations + } + } + } +}