github.com/status-im/status-go@v1.1.0/services/wallet/common/log_parser.go (about)

     1  // Moved here because transactions package depends on accounts package which
     2  // depends on appdatabase where this functionality is needed
     3  package common
     4  
     5  import (
     6  	"encoding/binary"
     7  	"fmt"
     8  	"math/big"
     9  
    10  	"github.com/ethereum/go-ethereum/common"
    11  	"github.com/ethereum/go-ethereum/core/types"
    12  	"github.com/ethereum/go-ethereum/crypto"
    13  	"github.com/ethereum/go-ethereum/log"
    14  )
    15  
    16  // Type type of transaction
    17  type Type string
    18  
    19  // Log Event type
    20  type EventType string
    21  
    22  const (
    23  	// Transaction types
    24  	EthTransfer        Type = "eth"
    25  	Erc20Transfer      Type = "erc20"
    26  	Erc721Transfer     Type = "erc721"
    27  	Erc1155Transfer    Type = "erc1155"
    28  	UniswapV2Swap      Type = "uniswapV2Swap"
    29  	UniswapV3Swap      Type = "uniswapV3Swap"
    30  	HopBridgeFrom      Type = "HopBridgeFrom"
    31  	HopBridgeTo        Type = "HopBridgeTo"
    32  	unknownTransaction Type = "unknown"
    33  
    34  	// Event types
    35  	WETHDepositEventType                      EventType = "wethDepositEvent"
    36  	WETHWithdrawalEventType                   EventType = "wethWithdrawalEvent"
    37  	Erc20TransferEventType                    EventType = "erc20Event"
    38  	Erc721TransferEventType                   EventType = "erc721Event"
    39  	Erc1155TransferSingleEventType            EventType = "erc1155SingleEvent"
    40  	Erc1155TransferBatchEventType             EventType = "erc1155BatchEvent"
    41  	UniswapV2SwapEventType                    EventType = "uniswapV2SwapEvent"
    42  	UniswapV3SwapEventType                    EventType = "uniswapV3SwapEvent"
    43  	HopBridgeTransferSentToL2EventType        EventType = "hopBridgeTransferSentToL2Event"
    44  	HopBridgeTransferFromL1CompletedEventType EventType = "hopBridgeTransferFromL1CompletedEvent"
    45  	HopBridgeWithdrawalBondedEventType        EventType = "hopBridgeWithdrawalBondedEvent"
    46  	HopBridgeTransferSentEventType            EventType = "hopBridgeTransferSentEvent"
    47  	UnknownEventType                          EventType = "unknownEvent"
    48  
    49  	// Deposit (index_topic_1 address dst, uint256 wad)
    50  	wethDepositEventSignature = "Deposit(address,uint256)"
    51  	// Withdrawal (index_topic_1 address src, uint256 wad)
    52  	wethWithdrawalEventSignature = "Withdrawal(address,uint256)"
    53  
    54  	// Transfer (index_topic_1 address from, index_topic_2 address to, uint256 value)
    55  	// Transfer (index_topic_1 address from, index_topic_2 address to, index_topic_3 uint256 tokenId)
    56  	Erc20_721TransferEventSignature     = "Transfer(address,address,uint256)"
    57  	Erc1155TransferSingleEventSignature = "TransferSingle(address,address,address,uint256,uint256)"    // operator, from, to, id, value
    58  	Erc1155TransferBatchEventSignature  = "TransferBatch(address,address,address,uint256[],uint256[])" // operator, from, to, ids, values
    59  
    60  	erc20TransferEventIndexedParameters   = 3 // signature, from, to
    61  	erc721TransferEventIndexedParameters  = 4 // signature, from, to, tokenId
    62  	erc1155TransferEventIndexedParameters = 4 // signature, operator, from, to (id, value are not indexed)
    63  
    64  	// Swap (index_topic_1 address sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, index_topic_2 address to)
    65  	uniswapV2SwapEventSignature = "Swap(address,uint256,uint256,uint256,uint256,address)" // also used by SushiSwap
    66  	// Swap (index_topic_1 address sender, index_topic_2 address recipient, int256 amount0, int256 amount1, uint160 sqrtPriceX96, uint128 liquidity, int24 tick)
    67  	uniswapV3SwapEventSignature = "Swap(address,address,int256,int256,uint160,uint128,int24)"
    68  
    69  	// TransferSentToL2 (index_topic_1 uint256 chainId, index_topic_2 address recipient, uint256 amount, uint256 amountOutMin, uint256 deadline, index_topic_3 address relayer, uint256 relayerFee)
    70  	hopBridgeTransferSentToL2EventSignature = "TransferSentToL2(uint256,address,uint256,uint256,uint256,address,uint256)"
    71  	// TransferFromL1Completed (index_topic_1 address recipient, uint256 amount, uint256 amountOutMin, uint256 deadline, index_topic_2 address relayer, uint256 relayerFee)
    72  	HopBridgeTransferFromL1CompletedEventSignature = "TransferFromL1Completed(address,uint256,uint256,uint256,address,uint256)"
    73  	// WithdrawalBonded (index_topic_1 bytes32 transferID, uint256 amount)
    74  	hopBridgeWithdrawalBondedEventSignature = "WithdrawalBonded(bytes32,uint256)"
    75  	// TransferSent (index_topic_1 bytes32 transferID, index_topic_2 uint256 chainId, index_topic_3 address recipient, uint256 amount, bytes32 transferNonce, uint256 bonderFee, uint256 index, uint256 amountOutMin, uint256 deadline)
    76  	hopBridgeTransferSentEventSignature = "TransferSent(bytes32,uint256,address,uint256,bytes32,uint256,uint256,uint256,uint256)"
    77  )
    78  
    79  var (
    80  	// MaxUint256 is the maximum value that can be represented by a uint256.
    81  	MaxUint256 = new(big.Int).Sub(new(big.Int).Lsh(common.Big1, 256), common.Big1)
    82  )
    83  
    84  // Detect event type for a cetain item from the Events Log
    85  func GetEventType(log *types.Log) EventType {
    86  	wethDepositEventSignatureHash := GetEventSignatureHash(wethDepositEventSignature)
    87  	wethWithdrawalEventSignatureHash := GetEventSignatureHash(wethWithdrawalEventSignature)
    88  	erc20_721TransferEventSignatureHash := GetEventSignatureHash(Erc20_721TransferEventSignature)
    89  	erc1155TransferSingleEventSignatureHash := GetEventSignatureHash(Erc1155TransferSingleEventSignature)
    90  	erc1155TransferBatchEventSignatureHash := GetEventSignatureHash(Erc1155TransferBatchEventSignature)
    91  	uniswapV2SwapEventSignatureHash := GetEventSignatureHash(uniswapV2SwapEventSignature)
    92  	uniswapV3SwapEventSignatureHash := GetEventSignatureHash(uniswapV3SwapEventSignature)
    93  	hopBridgeTransferSentToL2EventSignatureHash := GetEventSignatureHash(hopBridgeTransferSentToL2EventSignature)
    94  	hopBridgeTransferFromL1CompletedEventSignatureHash := GetEventSignatureHash(HopBridgeTransferFromL1CompletedEventSignature)
    95  	hopBridgeWithdrawalBondedEventSignatureHash := GetEventSignatureHash(hopBridgeWithdrawalBondedEventSignature)
    96  	hopBridgeTransferSentEventSignatureHash := GetEventSignatureHash(hopBridgeTransferSentEventSignature)
    97  
    98  	if len(log.Topics) > 0 {
    99  		switch log.Topics[0] {
   100  		case wethDepositEventSignatureHash:
   101  			return WETHDepositEventType
   102  		case wethWithdrawalEventSignatureHash:
   103  			return WETHWithdrawalEventType
   104  		case erc20_721TransferEventSignatureHash:
   105  			switch len(log.Topics) {
   106  			case erc20TransferEventIndexedParameters:
   107  				return Erc20TransferEventType
   108  			case erc721TransferEventIndexedParameters:
   109  				return Erc721TransferEventType
   110  			}
   111  		case erc1155TransferSingleEventSignatureHash:
   112  			return Erc1155TransferSingleEventType
   113  		case erc1155TransferBatchEventSignatureHash:
   114  			return Erc1155TransferBatchEventType
   115  		case uniswapV2SwapEventSignatureHash:
   116  			return UniswapV2SwapEventType
   117  		case uniswapV3SwapEventSignatureHash:
   118  			return UniswapV3SwapEventType
   119  		case hopBridgeTransferSentToL2EventSignatureHash:
   120  			return HopBridgeTransferSentToL2EventType
   121  		case hopBridgeTransferFromL1CompletedEventSignatureHash:
   122  			return HopBridgeTransferFromL1CompletedEventType
   123  		case hopBridgeWithdrawalBondedEventSignatureHash:
   124  			return HopBridgeWithdrawalBondedEventType
   125  		case hopBridgeTransferSentEventSignatureHash:
   126  			return HopBridgeTransferSentEventType
   127  		}
   128  	}
   129  
   130  	return UnknownEventType
   131  }
   132  
   133  func EventTypeToSubtransactionType(eventType EventType) Type {
   134  	switch eventType {
   135  	case Erc20TransferEventType:
   136  		return Erc20Transfer
   137  	case Erc721TransferEventType:
   138  		return Erc721Transfer
   139  	case Erc1155TransferSingleEventType, Erc1155TransferBatchEventType:
   140  		return Erc1155Transfer
   141  	case UniswapV2SwapEventType:
   142  		return UniswapV2Swap
   143  	case UniswapV3SwapEventType:
   144  		return UniswapV3Swap
   145  	case HopBridgeTransferSentToL2EventType, HopBridgeTransferSentEventType:
   146  		return HopBridgeFrom
   147  	case HopBridgeTransferFromL1CompletedEventType, HopBridgeWithdrawalBondedEventType:
   148  		return HopBridgeTo
   149  	}
   150  
   151  	return unknownTransaction
   152  }
   153  
   154  func GetFirstEvent(logs []*types.Log) (EventType, *types.Log) {
   155  	for _, log := range logs {
   156  		eventType := GetEventType(log)
   157  		if eventType != UnknownEventType {
   158  			return eventType, log
   159  		}
   160  	}
   161  
   162  	return UnknownEventType, nil
   163  }
   164  
   165  func IsTokenTransfer(logs []*types.Log) bool {
   166  	eventType, _ := GetFirstEvent(logs)
   167  	switch eventType {
   168  	case Erc20TransferEventType, Erc721TransferEventType, Erc1155TransferSingleEventType, Erc1155TransferBatchEventType:
   169  		return true
   170  	}
   171  
   172  	return false
   173  }
   174  
   175  func ParseWETHDepositLog(ethlog *types.Log) (src common.Address, amount *big.Int) {
   176  	amount = new(big.Int)
   177  
   178  	if len(ethlog.Topics) < 2 {
   179  		log.Warn("not enough topics for WETH deposit", "topics", ethlog.Topics)
   180  		return
   181  	}
   182  
   183  	if len(ethlog.Topics[1]) != 32 {
   184  		log.Warn("second topic is not padded to 32 byte address", "topic", ethlog.Topics[1])
   185  		return
   186  	}
   187  	copy(src[:], ethlog.Topics[1][12:])
   188  
   189  	if len(ethlog.Data) != 32 {
   190  		log.Warn("data is not padded to 32 byte big int", "data", ethlog.Data)
   191  		return
   192  	}
   193  	amount.SetBytes(ethlog.Data)
   194  
   195  	return
   196  }
   197  
   198  func ParseWETHWithdrawLog(ethlog *types.Log) (dst common.Address, amount *big.Int) {
   199  	amount = new(big.Int)
   200  
   201  	if len(ethlog.Topics) < 2 {
   202  		log.Warn("not enough topics for WETH withdraw", "topics", ethlog.Topics)
   203  		return
   204  	}
   205  
   206  	if len(ethlog.Topics[1]) != 32 {
   207  		log.Warn("second topic is not padded to 32 byte address", "topic", ethlog.Topics[1])
   208  		return
   209  	}
   210  	copy(dst[:], ethlog.Topics[1][12:])
   211  
   212  	if len(ethlog.Data) != 32 {
   213  		log.Warn("data is not padded to 32 byte big int", "data", ethlog.Data)
   214  		return
   215  	}
   216  	amount.SetBytes(ethlog.Data)
   217  
   218  	return
   219  }
   220  
   221  func ParseErc20TransferLog(ethlog *types.Log) (from, to common.Address, amount *big.Int) {
   222  	amount = new(big.Int)
   223  	if len(ethlog.Topics) < erc20TransferEventIndexedParameters {
   224  		log.Warn("not enough topics for erc20 transfer", "topics", ethlog.Topics)
   225  		return
   226  	}
   227  	var err error
   228  	from, to, err = getFromToAddresses(*ethlog)
   229  	if err != nil {
   230  		log.Error("log_parser::ParseErc20TransferLog", err)
   231  		return
   232  	}
   233  
   234  	if len(ethlog.Data) != 32 {
   235  		log.Warn("data is not padded to 32 byts big int", "data", ethlog.Data)
   236  		return
   237  	}
   238  	amount.SetBytes(ethlog.Data)
   239  
   240  	return
   241  }
   242  
   243  func ParseErc721TransferLog(ethlog *types.Log) (from, to common.Address, tokenID *big.Int) {
   244  	tokenID = new(big.Int)
   245  	if len(ethlog.Topics) < erc721TransferEventIndexedParameters {
   246  		log.Warn("not enough topics for erc721 transfer", "topics", ethlog.Topics)
   247  		return
   248  	}
   249  
   250  	var err error
   251  	from, to, err = getFromToAddresses(*ethlog)
   252  	if err != nil {
   253  		log.Error("log_parser::ParseErc721TransferLog", err)
   254  		return
   255  	}
   256  	tokenID.SetBytes(ethlog.Topics[3][:])
   257  
   258  	return
   259  }
   260  
   261  func GetLogSubTxID(log types.Log) common.Hash {
   262  	// Get unique ID by using TxHash and log index
   263  	index := [4]byte{}
   264  	binary.BigEndian.PutUint32(index[:], uint32(log.Index))
   265  	return crypto.Keccak256Hash(log.TxHash.Bytes(), index[:])
   266  }
   267  
   268  func getLogSubTxIDWithTokenIDIndex(log types.Log, tokenIDIdx uint16) common.Hash {
   269  	// Get unique ID by using TxHash, log index and extra bytes (token id index for ERC1155 TransferBatch)
   270  	index := [4]byte{}
   271  	value := uint32(log.Index&0x0000FFFF) | (uint32(tokenIDIdx) << 16) // log index should not exceed uint16 max value
   272  	binary.BigEndian.PutUint32(index[:], value)
   273  	return crypto.Keccak256Hash(log.TxHash.Bytes(), index[:])
   274  }
   275  
   276  func checkTopicsLength(ethlog types.Log, startIdx, endIdx int) (err error) {
   277  	for i := startIdx; i < endIdx; i++ {
   278  		if len(ethlog.Topics[i]) != common.HashLength {
   279  			err = fmt.Errorf("topic %d is not padded to %d byte address, topic=%s", i, common.HashLength, ethlog.Topics[i])
   280  			log.Error("log_parser::checkTopicsLength", err)
   281  			return
   282  		}
   283  	}
   284  	return
   285  }
   286  
   287  func getFromToAddresses(ethlog types.Log) (from, to common.Address, err error) {
   288  	eventType := GetEventType(&ethlog)
   289  	addressIdx := common.HashLength - common.AddressLength
   290  	switch eventType {
   291  	case Erc1155TransferSingleEventType, Erc1155TransferBatchEventType:
   292  		err = checkTopicsLength(ethlog, 2, 4)
   293  		if err != nil {
   294  			return
   295  		}
   296  		copy(from[:], ethlog.Topics[2][addressIdx:])
   297  		copy(to[:], ethlog.Topics[3][addressIdx:])
   298  		return
   299  
   300  	case Erc20TransferEventType, Erc721TransferEventType, UniswapV2SwapEventType, UniswapV3SwapEventType, HopBridgeTransferFromL1CompletedEventType:
   301  		err = checkTopicsLength(ethlog, 1, 3)
   302  		if err != nil {
   303  			return
   304  		}
   305  		copy(from[:], ethlog.Topics[1][addressIdx:])
   306  		copy(to[:], ethlog.Topics[2][addressIdx:])
   307  		return
   308  	}
   309  
   310  	return from, to, fmt.Errorf("unsupported event type to get from/to adddresses %s", eventType)
   311  }
   312  func ParseTransferLog(ethlog types.Log) (from, to common.Address, txIDs []common.Hash, tokenIDs, values []*big.Int, err error) {
   313  	eventType := GetEventType(&ethlog)
   314  
   315  	switch eventType {
   316  	case Erc20TransferEventType:
   317  		var amount *big.Int
   318  		from, to, amount = ParseErc20TransferLog(&ethlog)
   319  		txIDs = append(txIDs, GetLogSubTxID(ethlog))
   320  		values = append(values, amount)
   321  		return
   322  	case Erc721TransferEventType:
   323  		var tokenID *big.Int
   324  		from, to, tokenID = ParseErc721TransferLog(&ethlog)
   325  		txIDs = append(txIDs, GetLogSubTxID(ethlog))
   326  		tokenIDs = append(tokenIDs, tokenID)
   327  		values = append(values, big.NewInt(1))
   328  		return
   329  	case Erc1155TransferSingleEventType, Erc1155TransferBatchEventType:
   330  		_, from, to, tokenIDs, values, err = ParseErc1155TransferLog(&ethlog, eventType)
   331  		for i := range tokenIDs {
   332  			txIDs = append(txIDs, getLogSubTxIDWithTokenIDIndex(ethlog, uint16(i)))
   333  		}
   334  		return
   335  	}
   336  
   337  	return from, to, txIDs, tokenIDs, values, fmt.Errorf("unsupported event type in log_parser::ParseTransferLogs %s", eventType)
   338  }
   339  
   340  func ParseErc1155TransferLog(ethlog *types.Log, evType EventType) (operator, from, to common.Address, ids, amounts []*big.Int, err error) {
   341  	if len(ethlog.Topics) < erc1155TransferEventIndexedParameters {
   342  		err = fmt.Errorf("not enough topics for erc1155 transfer %s, %v", "topics", ethlog.Topics)
   343  		log.Error("log_parser::ParseErc1155TransferLog", "err", err)
   344  		return
   345  	}
   346  
   347  	err = checkTopicsLength(*ethlog, 1, erc1155TransferEventIndexedParameters)
   348  	if err != nil {
   349  		return
   350  	}
   351  
   352  	addressIdx := common.HashLength - common.AddressLength
   353  	copy(operator[:], ethlog.Topics[1][addressIdx:])
   354  	from, to, err = getFromToAddresses(*ethlog)
   355  	if err != nil {
   356  		log.Error("log_parser::ParseErc1155TransferLog", "err", err)
   357  		return
   358  	}
   359  
   360  	if len(ethlog.Data) == 0 || len(ethlog.Data)%(common.HashLength*2) != 0 {
   361  		err = fmt.Errorf("data is not padded to 64 bytes %s, %v", "data", ethlog.Data)
   362  		log.Error("log_parser::ParseErc1155TransferLog", "err", err)
   363  		return
   364  	}
   365  
   366  	if evType == Erc1155TransferSingleEventType {
   367  		ids = append(ids, new(big.Int).SetBytes(ethlog.Data[:common.HashLength]))
   368  		amounts = append(amounts, new(big.Int).SetBytes(ethlog.Data[common.HashLength:]))
   369  		log.Debug("log_parser::ParseErc1155TransferSingleLog", "ids", ids, "amounts", amounts)
   370  	} else {
   371  		// idTypeSize := new(big.Int).SetBytes(ethlog.Data[:common.HashLength]).Uint64() // Left for knowledge
   372  		// valueTypeSize := new(big.Int).SetBytes(ethlog.Data[common.HashLength : common.HashLength*2]).Uint64() // Left for knowledge
   373  		idsArraySize := new(big.Int).SetBytes(ethlog.Data[common.HashLength*2 : common.HashLength*2+common.HashLength]).Uint64()
   374  
   375  		initialOffset := common.HashLength*2 + common.HashLength
   376  		for i := 0; i < int(idsArraySize); i++ {
   377  			ids = append(ids, new(big.Int).SetBytes(ethlog.Data[initialOffset+i*common.HashLength:initialOffset+(i+1)*common.HashLength]))
   378  		}
   379  		valuesArraySize := new(big.Int).SetBytes(ethlog.Data[initialOffset+int(idsArraySize)*common.HashLength : initialOffset+int(idsArraySize+1)*common.HashLength]).Uint64()
   380  
   381  		if idsArraySize != valuesArraySize {
   382  			err = fmt.Errorf("ids and values sizes don't match %d, %d", idsArraySize, valuesArraySize)
   383  			log.Error("log_parser::ParseErc1155TransferBatchLog", "err", err)
   384  			return
   385  		}
   386  
   387  		initialOffset = initialOffset + int(idsArraySize+1)*common.HashLength
   388  		for i := 0; i < int(valuesArraySize); i++ {
   389  			amounts = append(amounts, new(big.Int).SetBytes(ethlog.Data[initialOffset+i*common.HashLength:initialOffset+(i+1)*common.HashLength]))
   390  			log.Debug("log_parser::ParseErc1155TransferBatchLog", "id", ids[i], "amount", amounts[i])
   391  		}
   392  	}
   393  
   394  	return
   395  }
   396  
   397  func ParseUniswapV2Log(ethlog *types.Log) (pairAddress common.Address, from common.Address, to common.Address, amount0In *big.Int, amount1In *big.Int, amount0Out *big.Int, amount1Out *big.Int, err error) {
   398  	amount0In = new(big.Int)
   399  	amount1In = new(big.Int)
   400  	amount0Out = new(big.Int)
   401  	amount1Out = new(big.Int)
   402  
   403  	if len(ethlog.Topics) < 3 {
   404  		err = fmt.Errorf("not enough topics for uniswapV2 swap %s, %v", "topics", ethlog.Topics)
   405  		return
   406  	}
   407  
   408  	pairAddress = ethlog.Address
   409  	from, to, err = getFromToAddresses(*ethlog)
   410  	if err != nil {
   411  		log.Error("log_parser::ParseUniswapV2Log", err)
   412  		return
   413  	}
   414  	if len(ethlog.Data) != 32*4 {
   415  		err = fmt.Errorf("data is not padded to 4 * 32 bytes big int %s, %v", "data", ethlog.Data)
   416  		return
   417  	}
   418  	amount0In.SetBytes(ethlog.Data[0:32])
   419  	amount1In.SetBytes(ethlog.Data[32:64])
   420  	amount0Out.SetBytes(ethlog.Data[64:96])
   421  	amount1Out.SetBytes(ethlog.Data[96:128])
   422  
   423  	return
   424  }
   425  
   426  func readInt256(b []byte) *big.Int {
   427  	// big.SetBytes can't tell if a number is negative or positive in itself.
   428  	// On EVM, if the returned number > max int256, it is negative.
   429  	// A number is > max int256 if the bit at position 255 is set.
   430  	ret := new(big.Int).SetBytes(b)
   431  	if ret.Bit(255) == 1 {
   432  		ret.Add(MaxUint256, new(big.Int).Neg(ret))
   433  		ret.Add(ret, common.Big1)
   434  		ret.Neg(ret)
   435  	}
   436  	return ret
   437  }
   438  
   439  func ParseUniswapV3Log(ethlog *types.Log) (poolAddress common.Address, sender common.Address, recipient common.Address, amount0 *big.Int, amount1 *big.Int, err error) {
   440  	amount0 = new(big.Int)
   441  	amount1 = new(big.Int)
   442  
   443  	if len(ethlog.Topics) < 3 {
   444  		err = fmt.Errorf("not enough topics for uniswapV3 swap %s, %v", "topics", ethlog.Topics)
   445  		return
   446  	}
   447  
   448  	poolAddress = ethlog.Address
   449  	sender, recipient, err = getFromToAddresses(*ethlog)
   450  	if err != nil {
   451  		log.Error("log_parser::ParseUniswapV3Log", err)
   452  		return
   453  	}
   454  	if len(ethlog.Data) != 32*5 {
   455  		err = fmt.Errorf("data is not padded to 5 * 32 bytes big int %s, %v", "data", ethlog.Data)
   456  		return
   457  	}
   458  	amount0 = readInt256(ethlog.Data[0:32])
   459  	amount1 = readInt256(ethlog.Data[32:64])
   460  
   461  	return
   462  }
   463  
   464  func ParseHopBridgeTransferSentToL2Log(ethlog *types.Log) (chainID uint64, recipient common.Address, relayer common.Address, amount *big.Int, err error) {
   465  	chainIDInt := new(big.Int)
   466  	amount = new(big.Int)
   467  
   468  	if len(ethlog.Topics) < 4 {
   469  		err = fmt.Errorf("not enough topics for HopBridgeTransferSentToL2 event %s, %v", "topics", ethlog.Topics)
   470  		return
   471  	}
   472  
   473  	if len(ethlog.Topics[1]) != 32 {
   474  		err = fmt.Errorf("second topic is not padded to 32 byte address %s, %v", "topic", ethlog.Topics[1])
   475  		return
   476  	}
   477  	chainIDInt.SetBytes(ethlog.Topics[1][:])
   478  	chainID = chainIDInt.Uint64()
   479  
   480  	if len(ethlog.Topics[2]) != 32 {
   481  		err = fmt.Errorf("third topic is not padded to 32 byte address %s, %v", "topic", ethlog.Topics[2])
   482  		return
   483  	}
   484  	copy(recipient[:], ethlog.Topics[2][12:])
   485  
   486  	if len(ethlog.Topics[3]) != 32 {
   487  		err = fmt.Errorf("fourth topic is not padded to 32 byte address %s, %v", "topic", ethlog.Topics[3])
   488  		return
   489  	}
   490  	copy(relayer[:], ethlog.Topics[3][12:])
   491  
   492  	if len(ethlog.Data) != 32*4 {
   493  		err = fmt.Errorf("data is not padded to 4 * 32 bytes big int %s, %v", "data", ethlog.Data)
   494  		return
   495  	}
   496  
   497  	amount.SetBytes(ethlog.Data[0:32])
   498  
   499  	return
   500  }
   501  
   502  func ParseHopBridgeTransferFromL1CompletedLog(ethlog *types.Log) (recipient common.Address, relayer common.Address, amount *big.Int, err error) {
   503  	amount = new(big.Int)
   504  
   505  	if len(ethlog.Topics) < 3 {
   506  		err = fmt.Errorf("not enough topics for HopBridgeTransferFromL1Completed event %s, %v", "topics", ethlog.Topics)
   507  		return
   508  	}
   509  
   510  	recipient, relayer, err = getFromToAddresses(*ethlog)
   511  	if err != nil {
   512  		log.Error("log_parser::ParseHopBridgeTransferFromL1CompletedLog", err)
   513  		return
   514  	}
   515  
   516  	if len(ethlog.Data) != 32*4 {
   517  		err = fmt.Errorf("data is not padded to 4 * 32 bytes big int %s, %v", "data", ethlog.Data)
   518  		return
   519  	}
   520  
   521  	amount.SetBytes(ethlog.Data[0:32])
   522  
   523  	return
   524  }
   525  
   526  func ParseHopWithdrawalBondedLog(ethlog *types.Log) (transferID *big.Int, amount *big.Int, err error) {
   527  	transferID = new(big.Int)
   528  	amount = new(big.Int)
   529  
   530  	if len(ethlog.Topics) < 2 {
   531  		err = fmt.Errorf("not enough topics for HopWithdrawalBonded event %s, %v", "topics", ethlog.Topics)
   532  		return
   533  	}
   534  
   535  	if len(ethlog.Topics[1]) != 32 {
   536  		err = fmt.Errorf("second topic is not padded to 32 byte address %s, %v", "topic", ethlog.Topics[1])
   537  		return
   538  	}
   539  	transferID.SetBytes(ethlog.Topics[1][:])
   540  
   541  	if len(ethlog.Data) != 32*1 {
   542  		err = fmt.Errorf("data is not padded to 1 * 32 bytes big int %s, %v", "data", ethlog.Data)
   543  		return
   544  	}
   545  
   546  	amount.SetBytes(ethlog.Data[0:32])
   547  
   548  	return
   549  }
   550  
   551  func ParseHopBridgeTransferSentLog(ethlog *types.Log) (transferID *big.Int, chainID uint64, recipient common.Address, amount *big.Int, transferNonce *big.Int, bonderFee *big.Int, index *big.Int, amountOutMin *big.Int, deadline *big.Int, err error) {
   552  	transferID = new(big.Int)
   553  	chainIDInt := new(big.Int)
   554  	amount = new(big.Int)
   555  	transferNonce = new(big.Int)
   556  	bonderFee = new(big.Int)
   557  	index = new(big.Int)
   558  	amountOutMin = new(big.Int)
   559  	deadline = new(big.Int)
   560  
   561  	if len(ethlog.Topics) < 4 {
   562  		err = fmt.Errorf("not enough topics for HopBridgeTransferSent event %s, %v", "topics", ethlog.Topics)
   563  		return
   564  	}
   565  
   566  	if len(ethlog.Topics[1]) != 32 {
   567  		err = fmt.Errorf("second topic is not padded to 32 byte big int %s, %v", "topic", ethlog.Topics[1])
   568  		return
   569  	}
   570  	transferID.SetBytes(ethlog.Topics[1][:])
   571  
   572  	if len(ethlog.Topics[2]) != 32 {
   573  		err = fmt.Errorf("third topic is not padded to 32 byte big int %s, %v", "topic", ethlog.Topics[2])
   574  		return
   575  	}
   576  	chainIDInt.SetBytes(ethlog.Topics[2][:])
   577  	chainID = chainIDInt.Uint64()
   578  
   579  	if len(ethlog.Topics[3]) != 32 {
   580  		err = fmt.Errorf("fourth topic is not padded to 32 byte address %s, %v", "topic", ethlog.Topics[3])
   581  		return
   582  	}
   583  	copy(recipient[:], ethlog.Topics[2][12:])
   584  
   585  	if len(ethlog.Data) != 32*6 {
   586  		err = fmt.Errorf("data is not padded to 6 * 32 bytes big int %s, %v", "data", ethlog.Data)
   587  		return
   588  	}
   589  
   590  	amount.SetBytes(ethlog.Data[0:32])
   591  	transferNonce.SetBytes(ethlog.Data[32:64])
   592  	bonderFee.SetBytes(ethlog.Data[64:96])
   593  	index.SetBytes(ethlog.Data[96:128])
   594  	amountOutMin.SetBytes(ethlog.Data[128:160])
   595  	deadline.SetBytes(ethlog.Data[160:192])
   596  
   597  	return
   598  }
   599  
   600  func GetEventSignatureHash(signature string) common.Hash {
   601  	return crypto.Keccak256Hash([]byte(signature))
   602  }
   603  
   604  func ExtractTokenTransferData(dbEntryType Type, log *types.Log, tx *types.Transaction) (correctType Type, tokenAddress *common.Address, txFrom *common.Address, txTo *common.Address) {
   605  	// erc721 transfers share signature with erc20 ones, so they both used to be categorized as erc20
   606  	// by the Downloader. We fix this here since they might be mis-categorized in the db.
   607  	if dbEntryType == Erc20Transfer {
   608  		eventType := GetEventType(log)
   609  		correctType = EventTypeToSubtransactionType(eventType)
   610  	} else {
   611  		correctType = dbEntryType
   612  	}
   613  
   614  	switch correctType {
   615  	case Erc20Transfer:
   616  		tokenAddress = new(common.Address)
   617  		*tokenAddress = log.Address
   618  		from, to, _ := ParseErc20TransferLog(log)
   619  		txFrom = &from
   620  		txTo = &to
   621  	case Erc721Transfer:
   622  		tokenAddress = new(common.Address)
   623  		*tokenAddress = log.Address
   624  		from, to, _ := ParseErc721TransferLog(log)
   625  		txFrom = &from
   626  		txTo = &to
   627  	case Erc1155Transfer:
   628  		tokenAddress = new(common.Address)
   629  		*tokenAddress = log.Address
   630  		_, from, to, _, _, err := ParseErc1155TransferLog(log, Erc1155TransferSingleEventType) // from/to extraction is the same for single and batch
   631  		if err != nil {
   632  			return
   633  		}
   634  		txFrom = &from
   635  		txTo = &to
   636  	}
   637  
   638  	return
   639  }
   640  
   641  func TxDataContainsAddress(txType uint8, txData []byte, address common.Address) bool {
   642  	// First 4 bytes are related to the methodID
   643  	const methodIDLen int = 4
   644  	const paramLen int = 32
   645  
   646  	var paramOffset int = 0
   647  	switch txType {
   648  	case types.OptimismDepositTxType:
   649  		// Offset for relayMessage data.
   650  		// I actually don't know what the 2x32 + 4 bytes mean, but it seems to be constant in all transactions I've
   651  		// checked. Will update the comment when I find out more about it.
   652  		paramOffset = 5*32 + 2*32 + 4
   653  	}
   654  
   655  	// Check if address is contained in any 32-byte parameter
   656  	for paramStart := methodIDLen + paramOffset; paramStart < len(txData); paramStart += paramLen {
   657  		paramEnd := paramStart + paramLen
   658  
   659  		if paramEnd > len(txData) {
   660  			break
   661  		}
   662  
   663  		// Address bytes should be in the last addressLen positions
   664  		paramBytes := txData[paramStart:paramEnd]
   665  		paramAddress := common.BytesToAddress(paramBytes)
   666  		if address == paramAddress {
   667  			return true
   668  		}
   669  	}
   670  	return false
   671  }