diff --git a/Sources/ChatFeature/Controllers/SheetController.swift b/Sources/ChatFeature/Controllers/SheetController.swift
index f0f4fde8279ddd39cf785ec6f1dd2e310563d4b6..974f086d5df232b982c0ab101b0f04f48f1bc578 100644
--- a/Sources/ChatFeature/Controllers/SheetController.swift
+++ b/Sources/ChatFeature/Controllers/SheetController.swift
@@ -5,6 +5,7 @@ final class SheetController: UIViewController {
     enum Action {
         case clear
         case details
+        case report
     }
 
     lazy private var screenView = SheetView()
@@ -23,7 +24,7 @@ final class SheetController: UIViewController {
     public override func viewDidLoad() {
         super.viewDidLoad()
 
-        screenView.clear
+        screenView.clearButton
             .publisher(for: .touchUpInside)
             .sink { [unowned self] in
                 dismiss(animated: true) { [weak actionRelay] in
@@ -31,12 +32,20 @@ final class SheetController: UIViewController {
                 }
             }.store(in: &cancellables)
 
-        screenView.details
+        screenView.detailsButton
             .publisher(for: .touchUpInside)
             .sink { [unowned self] in
                 dismiss(animated: true) { [weak actionRelay] in
                     actionRelay?.send(.details)
                 }
             }.store(in: &cancellables)
+
+        screenView.reportButton
+            .publisher(for: .touchUpInside)
+            .sink { [unowned self] in
+                dismiss(animated: true) { [weak actionRelay] in
+                    actionRelay?.send(.report)
+                }
+            }.store(in: &cancellables)
     }
 }
diff --git a/Sources/ChatFeature/Controllers/SingleChatController.swift b/Sources/ChatFeature/Controllers/SingleChatController.swift
index d1d7785af5663f567a8803fce22aa107cbfe0934..81fa1c7cdb6f821121e8c72e14daf0bb9077e757 100644
--- a/Sources/ChatFeature/Controllers/SingleChatController.swift
+++ b/Sources/ChatFeature/Controllers/SingleChatController.swift
@@ -187,6 +187,7 @@ public final class SingleChatController: UIViewController {
 
         navigationItem.rightBarButtonItem = UIBarButtonItem(customView: moreButton)
         navigationItem.leftBarButtonItem = UIBarButtonItem(customView: infoView)
+        navigationItem.leftItemsSupplementBackButton = true
     }
 
     private func setupInputController() {
@@ -249,6 +250,8 @@ public final class SingleChatController: UIViewController {
                     presentDeleteAllDrawer()
                 case .details:
                     coordinator.toContact(viewModel.contact, from: self)
+                case .report:
+                    presentReportDrawer()
                 }
             }.store(in: &cancellables)
 
@@ -263,6 +266,12 @@ public final class SingleChatController: UIViewController {
                 }
             }.store(in: &cancellables)
 
+        viewModel.reportPopupPublisher
+            .receive(on: DispatchQueue.main)
+            .sink { [unowned self] in
+                presentReportDrawer()
+            }.store(in: &cancellables)
+
         viewModel.isOnline
             .removeDuplicates()
             .receive(on: DispatchQueue.main)
@@ -383,6 +392,77 @@ public final class SingleChatController: UIViewController {
         return drawer
     }
 
+    private func presentReportDrawer() {
+        let cancelButton = CapsuleButton()
+        cancelButton.setStyle(.seeThrough)
+        cancelButton.setTitle(Localized.Chat.Report.cancel, for: .normal)
+
+        let reportButton = CapsuleButton()
+        reportButton.setStyle(.red)
+        reportButton.setTitle(Localized.Chat.Report.action, for: .normal)
+
+        let drawer = DrawerController(with: [
+            DrawerImage(
+                image: Asset.drawerNegative.image
+            ),
+            DrawerText(
+                font: Fonts.Mulish.semiBold.font(size: 18.0),
+                text: Localized.Chat.Report.title,
+                color: Asset.neutralActive.color
+            ),
+            DrawerText(
+                font: Fonts.Mulish.semiBold.font(size: 14.0),
+                text: Localized.Chat.Report.subtitle,
+                color: Asset.neutralWeak.color,
+                lineHeightMultiple: 1.35,
+                spacingAfter: 25
+            ),
+            DrawerStack(
+                axis: .vertical,
+                spacing: 20.0,
+                views: [reportButton, cancelButton]
+            )
+        ])
+
+        reportButton.publisher(for: .touchUpInside)
+            .receive(on: DispatchQueue.main)
+            .sink {
+                drawer.dismiss(animated: true) { [weak self] in
+                    guard let self = self else { return }
+                    self.drawerCancellables.removeAll()
+                    self.didProceedWithReport()
+                }
+            }.store(in: &drawerCancellables)
+
+        cancelButton.publisher(for: .touchUpInside)
+            .receive(on: DispatchQueue.main)
+            .sink {
+                drawer.dismiss(animated: true) { [weak self] in
+                    self?.drawerCancellables.removeAll()
+                }
+            }.store(in: &drawerCancellables)
+
+        coordinator.toDrawer(drawer, from: self)
+    }
+
+    private func didProceedWithReport() {
+        var screenshotImage: UIImage?
+
+        let layer = UIApplication.shared.keyWindow!.layer
+
+        let scale = UIScreen.main.scale
+        UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);
+        guard let context = UIGraphicsGetCurrentContext() else { return }
+        layer.render(in: context)
+
+        if let image = UIGraphicsGetImageFromCurrentImageContext() {
+            UIGraphicsEndImageContext()
+            UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
+            viewModel.uploadReport(screenshot: image)
+            navigationController?.popViewController(animated: true)
+        }
+    }
+
     private func presentDeleteAllDrawer() {
         let clearButton = CapsuleButton()
         clearButton.setStyle(.red)
@@ -632,7 +712,8 @@ extension SingleChatController: UICollectionViewDelegate {
                 ActionFactory.build(from: item, action: .copy, closure: self.viewModel.didRequestCopy(_:)),
                 ActionFactory.build(from: item, action: .retry, closure: self.viewModel.didRequestRetry(_:)),
                 ActionFactory.build(from: item, action: .reply, closure: self.viewModel.didRequestReply(_:)),
-                ActionFactory.build(from: item, action: .delete, closure: self.viewModel.didRequestDeleteSingle(_:))
+                ActionFactory.build(from: item, action: .delete, closure: self.viewModel.didRequestDeleteSingle(_:)),
+                ActionFactory.build(from: item, action: .report, closure: self.viewModel.didRequestReport(_:))
             ].compactMap { $0 })
         }
     }
diff --git a/Sources/ChatFeature/Helpers/CellConfigurator.swift b/Sources/ChatFeature/Helpers/CellConfigurator.swift
index 4f0ad3ca31e71223f57f6b9593b918c1f745c2e1..d9b61fd9d3be46405ab170259dbe82aa0b1961a0 100644
--- a/Sources/ChatFeature/Helpers/CellConfigurator.swift
+++ b/Sources/ChatFeature/Helpers/CellConfigurator.swift
@@ -399,6 +399,7 @@ struct ActionFactory {
         case retry
         case reply
         case delete
+        case report
 
         var title: String {
             switch self {
@@ -411,6 +412,8 @@ struct ActionFactory {
                 return Localized.Chat.BubbleMenu.reply
             case .delete:
                 return Localized.Chat.BubbleMenu.delete
+            case .report:
+                return Localized.Chat.BubbleMenu.report
             }
         }
     }
@@ -422,6 +425,8 @@ struct ActionFactory {
     ) -> UIAction? {
 
         switch action {
+        case .report:
+            guard item.status == .received else { return nil }
         case .reply:
             guard item.status == .received || item.status == .sent else { return nil }
         case .retry:
diff --git a/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift b/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift
index f51a893610402c317f938f0b29445317de9bb6d4..cf9404a325ff094c54a84708478f9ee0fd527c7c 100644
--- a/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift
+++ b/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift
@@ -34,6 +34,7 @@ final class SingleChatViewModel {
     private let replySubject = PassthroughSubject<(String, String), Never>()
     private let navigationRoutes = PassthroughSubject<SingleChatNavigationRoutes, Never>()
     private let sectionsRelay = CurrentValueSubject<[ArraySection<ChatSection, Message>], Never>([])
+    private let reportPopupSubject = PassthroughSubject<Void, Never>()
 
     var hud: AnyPublisher<HUDStatus, Never> { hudRelay.eraseToAnyPublisher() }
     private let hudRelay = CurrentValueSubject<HUDStatus, Never>(.none)
@@ -44,6 +45,10 @@ final class SingleChatViewModel {
     var navigation: AnyPublisher<SingleChatNavigationRoutes, Never> { navigationRoutes.eraseToAnyPublisher() }
     var shouldDisplayEmptyView: AnyPublisher<Bool, Never> { sectionsRelay.map { $0.isEmpty }.eraseToAnyPublisher() }
 
+    var reportPopupPublisher: AnyPublisher<Void, Never> {
+        reportPopupSubject.eraseToAnyPublisher()
+    }
+
     var messages: AnyPublisher<[ArraySection<ChatSection, Message>], Never> {
         sectionsRelay.map { sections -> [ArraySection<ChatSection, Message>] in
             var snapshot = [ArraySection<ChatSection, Message>]()
@@ -172,6 +177,10 @@ final class SingleChatViewModel {
         didRequestDelete([model])
     }
 
+    func didRequestReport(_: Message) {
+        reportPopupSubject.send()
+    }
+
     func abortReply() {
         stagedReply = nil
     }
@@ -211,6 +220,14 @@ final class SingleChatViewModel {
         return (contactTitle, message.text)
     }
 
+    func uploadReport(screenshot: UIImage) {
+        UIImageWriteToSavedPhotosAlbum(screenshot, nil, nil, nil)
+
+        var contact = contact
+        contact.isBlocked = true
+        _ = try? session.dbManager.saveContact(contact)
+    }
+
     func showRoundFrom(_ roundURL: String?) {
         if let urlString = roundURL, !urlString.isEmpty {
             navigationRoutes.send(.webview(urlString))
diff --git a/Sources/ChatFeature/Views/SheetView.swift b/Sources/ChatFeature/Views/SheetView.swift
index 86459e76e8947df8728e3daaa4569d62e8e5c7cd..a4cdfeb1348a6cd8b369115d6c34272df7649d87 100644
--- a/Sources/ChatFeature/Views/SheetView.swift
+++ b/Sources/ChatFeature/Views/SheetView.swift
@@ -2,9 +2,10 @@ import UIKit
 import Shared
 
 final class SheetView: UIView {
-    let stack = UIStackView()
-    let clear = SheetButton()
-    let details = SheetButton()
+    let stackView = UIStackView()
+    let clearButton = SheetButton()
+    let reportButton = SheetButton()
+    let detailsButton = SheetButton()
 
     init() {
         super.init(frame: .zero)
@@ -13,23 +14,28 @@ final class SheetView: UIView {
         layer.masksToBounds = true
         backgroundColor = Asset.neutralWhite.color
 
-        clear.image.image = Asset.chatListDeleteSwipe.image
-        clear.title.text = Localized.Chat.SheetMenu.clear
+        clearButton.image.image = Asset.chatListDeleteSwipe.image
+        clearButton.title.text = Localized.Chat.SheetMenu.clear
 
-        details.tintColor = Asset.neutralDark.color
-        details.image.image = Asset.searchUsername.image
-        details.title.text = Localized.Chat.SheetMenu.details
+        detailsButton.tintColor = Asset.neutralDark.color
+        detailsButton.image.image = Asset.searchUsername.image
+        detailsButton.title.text = Localized.Chat.SheetMenu.details
 
-        stack.axis = .vertical
-        stack.distribution = .fillEqually
-        stack.addArrangedSubview(clear)
-        stack.addArrangedSubview(details)
-        addSubview(stack)
+        reportButton.tintColor = Asset.accentDanger.color
+        reportButton.image.image = Asset.searchUsername.image
+        reportButton.title.text = Localized.Chat.SheetMenu.report
 
-        stack.snp.makeConstraints { make in
-            make.top.equalToSuperview().offset(25)
-            make.left.right.equalToSuperview()
-            make.bottom.equalTo(safeAreaLayoutGuide)
+        stackView.axis = .vertical
+        stackView.distribution = .fillEqually
+        stackView.addArrangedSubview(clearButton)
+        stackView.addArrangedSubview(detailsButton)
+        stackView.addArrangedSubview(reportButton)
+        addSubview(stackView)
+
+        stackView.snp.makeConstraints {
+            $0.top.equalToSuperview().offset(25)
+            $0.left.right.equalToSuperview()
+            $0.bottom.equalTo(safeAreaLayoutGuide)
         }
     }
 
diff --git a/Sources/ChatListFeature/ViewModel/ChatListViewModel.swift b/Sources/ChatListFeature/ViewModel/ChatListViewModel.swift
index f481b96fb7e3e14b74096919090bf1df8c96c840..efd5e463132d368e51255f3e52f346e9b602d018 100644
--- a/Sources/ChatListFeature/ViewModel/ChatListViewModel.swift
+++ b/Sources/ChatListFeature/ViewModel/ChatListViewModel.swift
@@ -107,7 +107,7 @@ final class ChatListViewModel {
             .confirmationFailed,
             .verificationFailed,
             .verificationInProgress
-        ])
+        ], isBlocked: false, isBanned: false)
 
         return Publishers.CombineLatest(
             session.dbManager.fetchContactsPublisher(contactsQuery).assertNoFailure(),
@@ -127,7 +127,9 @@ final class ChatListViewModel {
             ChatInfo.Query(
                 contactChatInfoQuery: .init(
                     userId: session.myId,
-                    authStatus: [.friend]
+                    authStatus: [.friend],
+                    isBlocked: false,
+                    isBanned: false
                 ),
                 groupChatInfoQuery: GroupChatInfo.Query(
                     authStatus: [.participating]
diff --git a/Sources/ContactListFeature/ViewModels/ContactListViewModel.swift b/Sources/ContactListFeature/ViewModels/ContactListViewModel.swift
index 0467446065b81d8f52a0f9517948160e623de1e2..f3fea8779375523d5ad7dd73ee4a7286e67d728a 100644
--- a/Sources/ContactListFeature/ViewModels/ContactListViewModel.swift
+++ b/Sources/ContactListFeature/ViewModels/ContactListViewModel.swift
@@ -8,7 +8,9 @@ final class ContactListViewModel {
     @Dependency private var session: SessionType
 
     var contacts: AnyPublisher<[Contact], Never> {
-        session.dbManager.fetchContactsPublisher(.init(authStatus: [.friend]))
+        let query = Contact.Query(authStatus: [.friend], isBlocked: false, isBanned: false)
+
+        return session.dbManager.fetchContactsPublisher(query)
             .assertNoFailure()
             .map { $0.filter { $0.id != self.session.myId }}
             .eraseToAnyPublisher()
@@ -22,7 +24,7 @@ final class ContactListViewModel {
             .confirmationFailed,
             .verificationFailed,
             .verificationInProgress
-        ])
+        ], isBlocked: false, isBanned: false)
 
         return Publishers.CombineLatest(
             session.dbManager.fetchContactsPublisher(contactsQuery).assertNoFailure(),
diff --git a/Sources/ContactListFeature/ViewModels/CreateGroupViewModel.swift b/Sources/ContactListFeature/ViewModels/CreateGroupViewModel.swift
index a8f94de8042f3cd7f7d0da14a9de703f217f573b..668b396b4f3955ceb8fb494234cd3cadf4f7b852 100644
--- a/Sources/ContactListFeature/ViewModels/CreateGroupViewModel.swift
+++ b/Sources/ContactListFeature/ViewModels/CreateGroupViewModel.swift
@@ -42,7 +42,7 @@ final class CreateGroupViewModel {
     // MARK: Lifecycle
 
     init() {
-        session.dbManager.fetchContactsPublisher(.init(authStatus: [.friend]))
+        session.dbManager.fetchContactsPublisher(.init(authStatus: [.friend], isBlocked: false, isBanned: false))
             .assertNoFailure()
             .map { $0.filter { $0.id != self.session.myId }}
             .map { $0.sorted(by: { $0.username! < $1.username! })}
diff --git a/Sources/MenuFeature/ViewModels/MenuViewModel.swift b/Sources/MenuFeature/ViewModels/MenuViewModel.swift
index b4ebd7571a0e3bafd60bb972310693af1c8fc02f..4d8b0db958870d5ee4aa90b7a383bb3dad91ab14 100644
--- a/Sources/MenuFeature/ViewModels/MenuViewModel.swift
+++ b/Sources/MenuFeature/ViewModels/MenuViewModel.swift
@@ -19,7 +19,7 @@ final class MenuViewModel {
             .confirmationFailed,
             .verificationFailed,
             .verificationInProgress
-        ])
+        ], isBlocked: false, isBanned: false)
 
         return Publishers.CombineLatest(
             session.dbManager.fetchContactsPublisher(contactsQuery).assertNoFailure(),
diff --git a/Sources/RequestsFeature/ViewModels/RequestsReceivedViewModel.swift b/Sources/RequestsFeature/ViewModels/RequestsReceivedViewModel.swift
index ded18f77a4da0d956d2bdb0b1779495c818d41f5..57efb1ea4dafa80cb33a86eab075d8042c7ed82f 100644
--- a/Sources/RequestsFeature/ViewModels/RequestsReceivedViewModel.swift
+++ b/Sources/RequestsFeature/ViewModels/RequestsReceivedViewModel.swift
@@ -65,7 +65,7 @@ final class RequestsReceivedViewModel {
                 .verified,
                 .verificationFailed,
                 .verificationInProgress
-            ])
+            ], isBlocked: false, isBanned: false)
 
         let groupStream = session.dbManager.fetchGroupsPublisher(groupsQuery).assertNoFailure()
         let contactsStream = session.dbManager.fetchContactsPublisher(contactsQuery).assertNoFailure()
diff --git a/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift b/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift
index f94ed8f5164de5c5a419a9b9271499ae7daa4952..26a6f485f1cb67721a301325e8eff5aefb917be5 100644
--- a/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift
+++ b/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift
@@ -36,7 +36,7 @@ final class RequestsSentViewModel {
         let query = Contact.Query(authStatus: [
             .requested,
             .requesting
-        ])
+        ], isBlocked: false, isBanned: false)
 
         session.dbManager.fetchContactsPublisher(query)
             .assertNoFailure()
diff --git a/Sources/SearchFeature/ViewModels/SearchLeftViewModel.swift b/Sources/SearchFeature/ViewModels/SearchLeftViewModel.swift
index 9f9d0ffd312f03a1d583a1ddebe12f1e8779f0da..7d49d19eadb1efb6eb3f82d48934e9bb1a0cefb2 100644
--- a/Sources/SearchFeature/ViewModels/SearchLeftViewModel.swift
+++ b/Sources/SearchFeature/ViewModels/SearchLeftViewModel.swift
@@ -144,7 +144,7 @@ final class SearchLeftViewModel {
         var snapshot = SearchSnapshot()
 
         if var user = user {
-            if let contact = try? session.dbManager.fetchContacts(.init(id: [user.id])).first {
+            if let contact = try? session.dbManager.fetchContacts(.init(id: [user.id], isBlocked: false, isBanned: false)).first {
                 user.authStatus = contact.authStatus
             }
 
diff --git a/Sources/Shared/AutoGenerated/Strings.swift b/Sources/Shared/AutoGenerated/Strings.swift
index 03ada00df323371aae8d22c05b50903f9da768d6..ee37eb4897d93ee82474119c917b6e770f74b35d 100644
--- a/Sources/Shared/AutoGenerated/Strings.swift
+++ b/Sources/Shared/AutoGenerated/Strings.swift
@@ -324,6 +324,8 @@ public enum Localized {
       public static let delete = Localized.tr("Localizable", "chat.bubbleMenu.delete")
       /// Reply
       public static let reply = Localized.tr("Localizable", "chat.bubbleMenu.reply")
+      /// Report
+      public static let report = Localized.tr("Localizable", "chat.bubbleMenu.report")
       /// Retry
       public static let retry = Localized.tr("Localizable", "chat.bubbleMenu.retry")
       /// Select
@@ -351,6 +353,16 @@ public enum Localized {
       /// All
       public static let deleteAll = Localized.tr("Localizable", "chat.menu.deleteAll")
     }
+    public enum Report {
+      /// Confirm and Report
+      public static let action = Localized.tr("Localizable", "chat.report.action")
+      /// Cancel
+      public static let cancel = Localized.tr("Localizable", "chat.report.cancel")
+      /// Reporting this user will block them, delete them from your connections and you won’t see direct messages from them again. In case this user is marked as banned user by us you won’t also see any new group chat msgs from this user
+      public static let subtitle = Localized.tr("Localizable", "chat.report.subtitle")
+      /// Report user
+      public static let title = Localized.tr("Localizable", "chat.report.title")
+    }
     public enum RetrySheet {
       /// Cancel
       public static let cancel = Localized.tr("Localizable", "chat.retrySheet.cancel")
@@ -370,6 +382,8 @@ public enum Localized {
       public static let clear = Localized.tr("Localizable", "chat.sheetMenu.clear")
       /// View contact profile
       public static let details = Localized.tr("Localizable", "chat.sheetMenu.details")
+      /// Report user
+      public static let report = Localized.tr("Localizable", "chat.sheetMenu.report")
     }
   }
 
diff --git a/Sources/Shared/Resources/en.lproj/Localizable.strings b/Sources/Shared/Resources/en.lproj/Localizable.strings
index 033e7a6f2ff8bd973d4eaf2cec0755295c8936b5..5d910155c0920d7008a3341664198240109337e5 100644
--- a/Sources/Shared/Resources/en.lproj/Localizable.strings
+++ b/Sources/Shared/Resources/en.lproj/Localizable.strings
@@ -114,6 +114,8 @@
 = "Select";
 "chat.bubbleMenu.retry"
 = "Retry";
+"chat.bubbleMenu.report"
+= "Report";
 
 "chat.e2e.placeholder"
 = "You and %@ now have a #quantum-secure#, completely private channel for messaging.\n#Say hello#!";
@@ -125,6 +127,8 @@
 = "Clear chat";
 "chat.sheetMenu.details"
 = "View contact profile";
+"chat.sheetMenu.report"
+= "Report user";
 "chat.retrySheet.retry"
 = "Try again";
 "chat.retrySheet.delete"
@@ -174,6 +178,17 @@
 "chat.clear.cancel"
 = "Cancel";
 
+// ChatFeature - Report
+
+"chat.report.title"
+= "Report user";
+"chat.report.subtitle"
+= "Reporting this user will block them, delete them from your connections and you won’t see direct messages from them again. In case this user is marked as banned user by us you won’t also see any new group chat msgs from this user";
+"chat.report.action"
+= "Confirm and Report";
+"chat.report.cancel"
+= "Cancel";
+
 // ScanFeature
 
 "scan.status.reading"