15: func (k msgServer) AddToInTxTracker(goCtx context.Context, msg *types.MsgAddToInTxTracker) (*types.MsgAddToInTxTrackerResponse, error) {
..    // [...]
26: 	isProven := false
27: 	if !(isAdmin || isObserver) && msg.Proof != nil {
28: 		txBytes, err := k.VerifyProof(ctx, msg.Proof, msg.ChainId, msg.BlockHash, msg.TxIndex)
29: 		if err != nil {
30: 			return nil, types.ErrProofVerificationFail.Wrapf(err.Error())
31: 		}
32:
33: 		if common.IsEVMChain(msg.ChainId) {
34: 			err = k.VerifyEVMInTxBody(ctx, msg, txBytes)
35: 			if err != nil {
36: 				return nil, types.ErrTxBodyVerificationFail.Wrapf(err.Error())
37: 			}
38: 		} else {
39: 			return nil, types.ErrTxBodyVerificationFail.Wrapf(fmt.Sprintf("cannot verify inTx body for chain %d", msg.ChainId))
40: 		}
41: 		isProven = true
42: 	}
..    // [...]
057: func (k Keeper) VerifyEVMInTxBody(ctx sdk.Context, msg *types.MsgAddToInTxTracker, txBytes []byte) error {
058: 	var txx ethtypes.Transaction
059: 	err := txx.UnmarshalBinary(txBytes)
060: 	if err != nil {
061: 		return err
062: 	}
063: 	if txx.Hash().Hex() != msg.TxHash {
064: 		return fmt.Errorf("want tx hash %s, got %s", txx.Hash().Hex(), msg.TxHash)
065: 	}
066: 	if txx.ChainId().Cmp(big.NewInt(msg.ChainId)) != 0 {
067: 		return fmt.Errorf("want evm chain id %d, got %d", txx.ChainId(), msg.ChainId)
068: 	}
069: 	switch msg.CoinType {
070: 	case common.CoinType_Zeta:
071: 		coreParams, found := k.zetaObserverKeeper.GetCoreParamsByChainID(ctx, msg.ChainId)
072: 		if !found {
073: 			return types.ErrUnsupportedChain.Wrapf("core params not found for chain %d", msg.ChainId)
074: 		}
075: 		if txx.To().Hex() != coreParams.ConnectorContractAddress {
076: 			return fmt.Errorf("receiver is not connector contract for coin type %s", msg.CoinType)
077: 		}
078: 		return nil
079: 	case common.CoinType_ERC20:
080: 		coreParams, found := k.zetaObserverKeeper.GetCoreParamsByChainID(ctx, msg.ChainId)
081: 		if !found {
082: 			return types.ErrUnsupportedChain.Wrapf("core params not found for chain %d", msg.ChainId)
083: 		}
084: 		if txx.To().Hex() != coreParams.Erc20CustodyContractAddress {
085: 			return fmt.Errorf("receiver is not erc20Custory contract for coin type %s", msg.CoinType)
086: 		}
087: 		return nil
088: 	case common.CoinType_Gas:
089: 		tss, err := k.GetTssAddress(ctx, &types.QueryGetTssAddressRequest{})
090: 		if err != nil {
091: 			return err
092: 		}
093: 		tssAddr := eth.HexToAddress(tss.Eth)
094: 		if tssAddr == (eth.Address{}) {
095: 			return fmt.Errorf("tss address not found")
096: 		}
097: 		if txx.To().Hex() != tssAddr.Hex() {
098: 			return fmt.Errorf("receiver is not tssAddress contract for coin type %s", msg.CoinType)
099: 		}
100: 		return nil
101: 	default:
102: 		return fmt.Errorf("coin type %s not supported", msg.CoinType)
103: 	}
104: }
