diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt
index c082b5b64e30e99ac9d2229f7db75ef77c8121b5..9bf3595fcd5690c4b7c42ed3faf752775f2af139 100644
--- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt
+++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/risklevel/ui/TestRiskLevelCalculationFragmentCWAViewModel.kt
@@ -10,7 +10,7 @@ import com.squareup.inject.assisted.AssistedInject
 import de.rki.coronawarnapp.appconfig.AppConfigProvider
 import de.rki.coronawarnapp.appconfig.ConfigData
 import de.rki.coronawarnapp.diagnosiskeys.download.DownloadDiagnosisKeysTask
-import de.rki.coronawarnapp.diagnosiskeys.download.KeyPackageSyncSettings
+import de.rki.coronawarnapp.diagnosiskeys.download.DownloadDiagnosisKeysSettings
 import de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheRepository
 import de.rki.coronawarnapp.nearby.modules.detectiontracker.ExposureDetectionTracker
 import de.rki.coronawarnapp.nearby.modules.detectiontracker.latestSubmission
@@ -57,7 +57,7 @@ class TestRiskLevelCalculationFragmentCWAViewModel @AssistedInject constructor(
     private val testSettings: TestSettings,
     private val timeStamper: TimeStamper,
     private val exposureDetectionTracker: ExposureDetectionTracker,
-    private val keyPackageSyncSettings: KeyPackageSyncSettings,
+    private val downloadDiagnosisKeysSettings: DownloadDiagnosisKeysSettings,
     private val submissionRepository: SubmissionRepository
 ) : CWAViewModel(
     dispatcherProvider = dispatcherProvider
@@ -241,7 +241,7 @@ class TestRiskLevelCalculationFragmentCWAViewModel @AssistedInject constructor(
         Timber.d("Clearing key cache")
         launch {
             keyCacheRepository.clear()
-            keyPackageSyncSettings.clear()
+            downloadDiagnosisKeysSettings.clear()
             exposureDetectionTracker.clear()
 
             dataResetEvent.postValue("Download & Submission related data reset.")
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/internal/AppConfigSource.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/internal/AppConfigSource.kt
index 1e5cc4959e860fec7548e6e1a1954451487261f8..e8d3ff9192777c40b494970353b95b0cdbd002ae 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/internal/AppConfigSource.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/appconfig/internal/AppConfigSource.kt
@@ -40,7 +40,7 @@ class AppConfigSource @Inject constructor(
                 localConfig
             }
             else -> {
-                Timber.tag(TAG).w("Remote & Local config available! Returning DEFAULT!")
+                Timber.tag(TAG).w("Remote & Local config unavailable! Returning DEFAULT!")
                 defaultAppConfigSource.getConfigData()
             }
         }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/KeyPackageSyncSettings.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/DownloadDiagnosisKeysSettings.kt
similarity index 58%
rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/KeyPackageSyncSettings.kt
rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/DownloadDiagnosisKeysSettings.kt
index 767788b052571ee50d306089dec02aba0a7513d6..942c9407578f4fc65ea739b83d8a14992dc48c8f 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/KeyPackageSyncSettings.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/DownloadDiagnosisKeysSettings.kt
@@ -2,17 +2,20 @@ package de.rki.coronawarnapp.diagnosiskeys.download
 
 import android.annotation.SuppressLint
 import android.content.Context
+import androidx.core.content.edit
 import com.google.gson.Gson
+import de.rki.coronawarnapp.environment.BuildConfigWrap
 import de.rki.coronawarnapp.util.di.AppContext
 import de.rki.coronawarnapp.util.preferences.FlowPreference
 import de.rki.coronawarnapp.util.preferences.clearAndNotify
 import de.rki.coronawarnapp.util.serialization.BaseGson
 import org.joda.time.Instant
+import timber.log.Timber
 import javax.inject.Inject
 import javax.inject.Singleton
 
 @Singleton
-class KeyPackageSyncSettings @Inject constructor(
+class DownloadDiagnosisKeysSettings @Inject constructor(
     @AppContext private val context: Context,
     @BaseGson private val gson: Gson
 ) {
@@ -34,6 +37,12 @@ class KeyPackageSyncSettings @Inject constructor(
         writer = FlowPreference.gsonWriter(gson)
     )
 
+    var lastVersionCode: Long
+        get() = prefs.getLong(KEY_LAST_VERSION_CODE, -1L)
+        set(value) = prefs.edit {
+            putLong(KEY_LAST_VERSION_CODE, value)
+        }
+
     @SuppressLint("ApplySharedPref")
     fun clear() {
         prefs.clearAndNotify()
@@ -45,4 +54,21 @@ class KeyPackageSyncSettings @Inject constructor(
         val successful: Boolean = false,
         val newData: Boolean = false
     )
+
+    companion object {
+        private const val KEY_LAST_VERSION_CODE = "download.task.last.versionCode"
+        internal const val VERSION_CODE_FIRST_POSSIBLE_1_8_RELEASE = 1080000
+    }
+}
+
+/**
+ * true if, and only if, since last runtime the app was updated from 1.7 (or earlier) to a version >= 1.8.0
+ */
+val DownloadDiagnosisKeysSettings.isUpdateToEnfV2: Boolean
+    get() = lastVersionCode < DownloadDiagnosisKeysSettings.VERSION_CODE_FIRST_POSSIBLE_1_8_RELEASE
+
+fun DownloadDiagnosisKeysSettings.updateLastVersionCodeToCurrent() {
+    lastVersionCode = BuildConfigWrap.VERSION_CODE.also {
+        Timber.d("lastVersionCode updated to %d", it)
+    }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/DownloadDiagnosisKeysTask.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/DownloadDiagnosisKeysTask.kt
index cd5bc298faa82904ddbf2c2610ed954ed4a98750..8f4f32f0d97dc6e9d5887232b292d152635b58ee 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/DownloadDiagnosisKeysTask.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/DownloadDiagnosisKeysTask.kt
@@ -6,7 +6,6 @@ import de.rki.coronawarnapp.appconfig.ExposureDetectionConfig
 import de.rki.coronawarnapp.diagnosiskeys.server.LocationCode
 import de.rki.coronawarnapp.environment.EnvironmentSetup
 import de.rki.coronawarnapp.nearby.ENFClient
-import de.rki.coronawarnapp.nearby.InternalExposureNotificationClient
 import de.rki.coronawarnapp.nearby.modules.detectiontracker.TrackedExposureDetection
 import de.rki.coronawarnapp.risk.RollbackItem
 import de.rki.coronawarnapp.task.Task
@@ -31,7 +30,8 @@ class DownloadDiagnosisKeysTask @Inject constructor(
     private val environmentSetup: EnvironmentSetup,
     private val appConfigProvider: AppConfigProvider,
     private val keyPackageSyncTool: KeyPackageSyncTool,
-    private val timeStamper: TimeStamper
+    private val timeStamper: TimeStamper,
+    private val settings: DownloadDiagnosisKeysSettings
 ) : Task<DownloadDiagnosisKeysTask.Progress, Task.Result> {
 
     private val internalProgress = ConflatedBroadcastChannel<Progress>()
@@ -51,7 +51,7 @@ class DownloadDiagnosisKeysTask @Inject constructor(
              * in a background job. Also it acts as a failure catch in case the orchestration code did
              * not check in before.
              */
-            if (!InternalExposureNotificationClient.asyncIsEnabled()) {
+            if (!enfClient.isTracingEnabled.first()) {
                 Timber.tag(TAG).w("EN is not enabled, skipping RetrieveDiagnosisKeys")
                 return object : Task.Result {}
             }
@@ -72,7 +72,6 @@ class DownloadDiagnosisKeysTask @Inject constructor(
             val keySyncResult = getAvailableKeyFiles(requestedCountries)
             throwIfCancelled()
 
-            val trackedExposureDetections = enfClient.latestTrackedExposureDetection().first()
             val now = timeStamper.nowUTC
 
             if (exposureConfig.maxExposureDetectionsPerUTCDay == 0) {
@@ -80,13 +79,17 @@ class DownloadDiagnosisKeysTask @Inject constructor(
                 return object : Task.Result {}
             }
 
-            if (wasLastDetectionPerformedRecently(now, exposureConfig, trackedExposureDetections)) {
+            val trackedExposureDetections = enfClient.latestTrackedExposureDetection().first()
+            val isUpdateToEnfV2 = settings.isUpdateToEnfV2
+
+            Timber.tag(TAG).d("isUpdateToEnfV2: %b", isUpdateToEnfV2)
+            if (!isUpdateToEnfV2 && wasLastDetectionPerformedRecently(now, exposureConfig, trackedExposureDetections)) {
                 // At most one detection every 6h
                 Timber.tag(TAG).i("task aborted, because detection was performed recently")
                 return object : Task.Result {}
             }
 
-            if (hasRecentDetectionAndNoNewFiles(now, keySyncResult, trackedExposureDetections)) {
+            if (!isUpdateToEnfV2 && hasRecentDetectionAndNoNewFiles(now, keySyncResult, trackedExposureDetections)) {
                 Timber.tag(TAG).i("task aborted, last check was within 24h, and there are no new files")
                 return object : Task.Result {}
             }
@@ -101,6 +104,9 @@ class DownloadDiagnosisKeysTask @Inject constructor(
                 )
             )
 
+            // remember version code of this execution for next time
+            settings.updateLastVersionCodeToCurrent()
+
             Timber.tag(TAG).d("Attempting submission to ENF")
             val isSubmissionSuccessful = enfClient.provideDiagnosisKeys(
                 availableKeyFiles,
@@ -161,7 +167,9 @@ class DownloadDiagnosisKeysTask @Inject constructor(
         }
     }
 
-    private suspend fun getAvailableKeyFiles(requestedCountries: List<String>?): KeyPackageSyncTool.Result {
+    private suspend fun getAvailableKeyFiles(
+        requestedCountries: List<String>?
+    ): KeyPackageSyncTool.Result {
         val wantedLocations = if (environmentSetup.useEuropeKeyPackageFiles) {
             listOf("EUR")
         } else {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/KeyPackageSyncTool.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/KeyPackageSyncTool.kt
index 9c8189c90e5015085a0b360b8d23999f8e662cd6..5388f534123f19c118d9a8583b7c749ba420d5cd 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/KeyPackageSyncTool.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/KeyPackageSyncTool.kt
@@ -15,7 +15,7 @@ class KeyPackageSyncTool @Inject constructor(
     private val keyCache: KeyCacheRepository,
     private val dayPackageSyncTool: DayPackageSyncTool,
     private val hourPackageSyncTool: HourPackageSyncTool,
-    private val syncSettings: KeyPackageSyncSettings,
+    private val syncSettings: DownloadDiagnosisKeysSettings,
     private val timeStamper: TimeStamper,
     private val networkStateProvider: NetworkStateProvider
 ) {
@@ -77,7 +77,7 @@ class KeyPackageSyncTool @Inject constructor(
         Timber.tag(TAG).d("Synchronizing available days (lastDownload=%s).", lastDownload)
 
         syncSettings.lastDownloadDays.update {
-            KeyPackageSyncSettings.LastDownload(startedAt = timeStamper.nowUTC)
+            DownloadDiagnosisKeysSettings.LastDownload(startedAt = timeStamper.nowUTC)
         }
 
         val syncResult = dayPackageSyncTool.syncMissingDayPackages(
@@ -104,7 +104,7 @@ class KeyPackageSyncTool @Inject constructor(
         Timber.tag(TAG).d("Synchronizing available hours (lastDownload=%s).", lastDownload)
 
         syncSettings.lastDownloadHours.update {
-            KeyPackageSyncSettings.LastDownload(
+            DownloadDiagnosisKeysSettings.LastDownload(
                 startedAt = timeStamper.nowUTC
             )
         }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/BuildConfigWrap.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/BuildConfigWrap.kt
index 8fc88e77f9cb9b5ce3f49404a59b1d16a5386d04..bc8252d1b7b923721b0e77cd6c85c08f43c4e678 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/BuildConfigWrap.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/BuildConfigWrap.kt
@@ -8,4 +8,6 @@ object BuildConfigWrap {
 
     val ENVIRONMENT_JSONDATA = BuildConfig.ENVIRONMENT_JSONDATA
     val ENVIRONMENT_TYPE_DEFAULT = BuildConfig.ENVIRONMENT_TYPE_DEFAULT
+
+    val VERSION_CODE: Long = BuildConfig.VERSION_CODE.toLong()
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/legacy/RiskLevelResultMigrator.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/legacy/RiskLevelResultMigrator.kt
index 0f60e67edfc2b0e1533ad3325acee636ef1aa86f..07f3a3fb3f6e6578f0c341aface0383151d020ef 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/legacy/RiskLevelResultMigrator.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/storage/legacy/RiskLevelResultMigrator.kt
@@ -1,5 +1,6 @@
 package de.rki.coronawarnapp.risk.storage.legacy
 
+import android.content.Context
 import android.content.SharedPreferences
 import androidx.annotation.VisibleForTesting
 import com.google.android.gms.nearby.exposurenotification.ExposureWindow
@@ -7,8 +8,11 @@ import dagger.Lazy
 import de.rki.coronawarnapp.risk.RiskLevelResult
 import de.rki.coronawarnapp.risk.RiskState
 import de.rki.coronawarnapp.risk.result.AggregatedRiskResult
+import de.rki.coronawarnapp.storage.AppDatabase
 import de.rki.coronawarnapp.storage.EncryptedPreferences
 import de.rki.coronawarnapp.util.TimeStamper
+import de.rki.coronawarnapp.util.di.AppContext
+import org.joda.time.Duration
 import org.joda.time.Instant
 import timber.log.Timber
 import javax.inject.Inject
@@ -22,60 +26,93 @@ import javax.inject.Singleton
 @Singleton
 class RiskLevelResultMigrator @Inject constructor(
     @EncryptedPreferences encryptedPreferences: Lazy<SharedPreferences>,
-    private val timeStamper: TimeStamper
+    private val timeStamper: TimeStamper,
+    @AppContext
+    private val context: Context
 ) {
 
     private val prefs by lazy { encryptedPreferences.get() }
 
     private fun lastTimeRiskLevelCalculation(): Instant? {
         prefs.getLong("preference_timestamp_risk_level_calculation", -1L).also {
+            Timber.tag(TAG).d("preference_timestamp_risk_level_calculation=$it")
             return if (it < 0) null else Instant.ofEpochMilli(it)
         }
     }
 
     private fun lastCalculatedRiskLevel(): RiskState? {
         val rawRiskLevel = prefs.getInt("preference_risk_level_score", -1)
+        Timber.tag(TAG).d("preference_risk_level_score=$rawRiskLevel")
         return if (rawRiskLevel != -1) mapRiskLevelConstant(rawRiskLevel) else null
     }
 
     private fun lastSuccessfullyCalculatedRiskLevel(): RiskState? {
         val rawRiskLevel = prefs.getInt("preference_risk_level_score_successful", -1)
+        Timber.tag(TAG).d("preference_risk_level_score_successful=$rawRiskLevel")
         return if (rawRiskLevel != -1) mapRiskLevelConstant(rawRiskLevel) else null
     }
 
-    fun getLegacyResults(): List<RiskLevelResult> = try {
+    private suspend fun lastEncounterAt(): Instant? {
+        return try {
+            val daysSinceLastExposure =
+                AppDatabase.getInstance(context)
+                    .exposureSummaryDao()
+                    .getLatestExposureSummary()?.daysSinceLastExposure
+            if (daysSinceLastExposure == null) {
+                null
+            } else {
+                timeStamper.nowUTC.minus(Duration.standardDays(daysSinceLastExposure.toLong()))
+            }
+        } catch (exception: Exception) {
+            Timber.tag(TAG).w(exception, "failed to select exposure summary dao from enf v1")
+            null
+        }
+    }
+
+    suspend fun getLegacyResults(): List<RiskLevelResult> = try {
         val legacyResults = mutableListOf<RiskLevelResult>()
         lastCalculatedRiskLevel()?.let {
             legacyResults.add(
                 LegacyResult(
                     riskState = it,
-                    calculatedAt = lastTimeRiskLevelCalculation() ?: timeStamper.nowUTC
+                    calculatedAt = lastTimeRiskLevelCalculation() ?: timeStamper.nowUTC,
+                    lastEncounterAt = lastEncounterAt()
                 )
             )
         }
 
         lastSuccessfullyCalculatedRiskLevel()?.let {
-            legacyResults.add(LegacyResult(riskState = it, calculatedAt = timeStamper.nowUTC))
+            legacyResults.add(
+                LegacyResult(
+                    riskState = it,
+                    calculatedAt = timeStamper.nowUTC,
+                    lastEncounterAt = lastEncounterAt()
+                )
+            )
         }
 
+        Timber.tag(TAG).d("legacyResults=$legacyResults")
         legacyResults
     } catch (e: Exception) {
-        Timber.e(e, "Failed to parse legacy risklevel data.")
+        Timber.tag(TAG).e(e, "Failed to parse legacy risklevel data.")
         emptyList()
     }
 
     data class LegacyResult(
         override val riskState: RiskState,
-        override val calculatedAt: Instant
+        override val calculatedAt: Instant,
+        private val lastEncounterAt: Instant?
     ) : RiskLevelResult {
         override val failureReason: RiskLevelResult.FailureReason? = null
         override val aggregatedRiskResult: AggregatedRiskResult? = null
         override val exposureWindows: List<ExposureWindow>? = null
         override val matchedKeyCount: Int = 0
         override val daysWithEncounters: Int = 0
+        override val lastRiskEncounterAt: Instant? = lastEncounterAt
     }
 
     companion object {
+        private const val TAG = "RiskLevelResultMigrator"
 
         @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
         internal fun mapRiskLevelConstant(value: Int): RiskState = when (value) {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardState.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardState.kt
index 8495f92558bb58fb6246e5b2e6ae2d942bbfd633..8faedf9b4348988f5127213fc396a84b2e13ce60 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardState.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/tracing/card/TracingCardState.kt
@@ -86,7 +86,9 @@ data class TracingCardState(
             ""
         }
         riskState == INCREASED_RISK && daysWithEncounters == 0 -> {
-            c.getString(R.string.risk_card_high_risk_no_encounters_body)
+            // LEGACY MIGRATION CASE FROM 1.7.x -> 1.8.x ('days with encounter' doesn't exit in 1.7.x)
+            // see RiskLevelResultMigrator.kt
+            ""
         }
         riskState == INCREASED_RISK -> {
             c.resources.getQuantityString(
@@ -96,6 +98,8 @@ data class TracingCardState(
             )
         }
         riskState == LOW_RISK && daysWithEncounters == 0 -> {
+            // caution! is 0 after migration from 1.7.x -> 1.8.x
+            // see RiskLevelResultMigrator.kt
             c.getString(R.string.risk_card_low_risk_no_encounters_body)
         }
         riskState == LOW_RISK -> {
@@ -126,10 +130,13 @@ data class TracingCardState(
      */
     fun getRiskContactLast(c: Context): String = when {
         isTracingOff() -> ""
-        riskState == INCREASED_RISK -> {
-            val formattedDate = lastEncounterAt?.toLocalDate()?.toString(DateTimeFormat.mediumDate())
-            c.getString(R.string.risk_card_high_risk_most_recent_body, formattedDate)
-        }
+        riskState == INCREASED_RISK && lastEncounterAt != null ->
+            // caution! lastEncounterAt is null after migration from 1.7.x -> 1.8.x
+            // see RiskLevelResultMigrator.kt
+            c.getString(
+                R.string.risk_card_high_risk_most_recent_body,
+                lastEncounterAt.toLocalDate().toString(DateTimeFormat.mediumDate())
+            )
         else -> ""
     }
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DataReset.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DataReset.kt
index 7673f4e16733553d6e9817bc3f604e55aa7206c5..e5438192ad55b436bd559dc31e998c7e162facd2 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DataReset.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DataReset.kt
@@ -22,7 +22,7 @@ package de.rki.coronawarnapp.util
 import android.annotation.SuppressLint
 import android.content.Context
 import de.rki.coronawarnapp.appconfig.AppConfigProvider
-import de.rki.coronawarnapp.diagnosiskeys.download.KeyPackageSyncSettings
+import de.rki.coronawarnapp.diagnosiskeys.download.DownloadDiagnosisKeysSettings
 import de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheRepository
 import de.rki.coronawarnapp.nearby.modules.detectiontracker.ExposureDetectionTracker
 import de.rki.coronawarnapp.risk.storage.RiskLevelStorage
@@ -49,7 +49,7 @@ class DataReset @Inject constructor(
     private val interoperabilityRepository: InteroperabilityRepository,
     private val submissionRepository: SubmissionRepository,
     private val exposureDetectionTracker: ExposureDetectionTracker,
-    private val keyPackageSyncSettings: KeyPackageSyncSettings,
+    private val downloadDiagnosisKeysSettings: DownloadDiagnosisKeysSettings,
     private val riskLevelStorage: RiskLevelStorage
 ) {
 
@@ -75,7 +75,7 @@ class DataReset @Inject constructor(
         appConfigProvider.clear()
         interoperabilityRepository.clear()
         exposureDetectionTracker.clear()
-        keyPackageSyncSettings.clear()
+        downloadDiagnosisKeysSettings.clear()
         riskLevelStorage.clear()
 
         Timber.w("CWA LOCAL DATA DELETION COMPLETED.")
diff --git a/Corona-Warn-App/src/main/res/values-de/strings.xml b/Corona-Warn-App/src/main/res/values-de/strings.xml
index dcece355b579c93069c886ac2f35c3f659082cda..ec76626547627e9547298defceb1262937dc7a71 100644
--- a/Corona-Warn-App/src/main/res/values-de/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-de/strings.xml
@@ -175,8 +175,6 @@
         <item quantity="many">"Begegnungen mit niedrigem Risiko an %1$d Tagen"</item>
     </plurals>
 
-    <!-- XTXT: risk card - High risk state - No days with high risk encounters -->
-    <string name="risk_card_high_risk_no_encounters_body">Keine Risiko-Begegnungen</string>
     <!-- XTXT: risk card - High risk state - Days with high risk encounters -->
     <plurals name="risk_card_high_risk_encounter_days_body">
         <item quantity="one">"Begegnungen an einem Tag mit erhöhtem Risiko"</item>
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/appconfig/mapping/ConfigParserTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/appconfig/mapping/ConfigParserTest.kt
index 22f65553bf124132ecd7df87bc67b821afbbbc2e..17ac5297ed7f48bccf82fec5fda51897c1655df0 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/appconfig/mapping/ConfigParserTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/appconfig/mapping/ConfigParserTest.kt
@@ -1,9 +1,13 @@
 package de.rki.coronawarnapp.appconfig.mapping
 
+import com.google.protobuf.InvalidProtocolBufferException
 import de.rki.coronawarnapp.appconfig.CWAConfig
 import de.rki.coronawarnapp.appconfig.ExposureDetectionConfig
 import de.rki.coronawarnapp.appconfig.ExposureWindowRiskCalculationConfig
 import de.rki.coronawarnapp.appconfig.KeyDownloadConfig
+import io.kotest.assertions.throwables.shouldThrow
+import io.kotest.matchers.shouldBe
+import io.kotest.matchers.shouldNotBe
 import io.mockk.MockKAnnotations
 import io.mockk.clearAllMocks
 import io.mockk.every
@@ -15,6 +19,7 @@ import org.junit.jupiter.api.AfterEach
 import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
 import testhelpers.BaseTest
+import java.io.File
 
 class ConfigParserTest : BaseTest() {
     @MockK lateinit var cwaConfigMapper: CWAConfig.Mapper
@@ -22,6 +27,9 @@ class ConfigParserTest : BaseTest() {
     @MockK lateinit var exposureDetectionConfigMapper: ExposureDetectionConfig.Mapper
     @MockK lateinit var exposureWindowRiskCalculationConfigMapper: ExposureWindowRiskCalculationConfig.Mapper
 
+    private val appConfig171 = File("src/test/resources/appconfig_1_7_1.bin")
+    private val appConfig180 = File("src/test/resources/appconfig_1_8_0.bin")
+
     @BeforeEach
     fun setup() {
         MockKAnnotations.init(this)
@@ -30,6 +38,9 @@ class ConfigParserTest : BaseTest() {
         every { keyDownloadConfigMapper.map(any()) } returns mockk()
         every { exposureDetectionConfigMapper.map(any()) } returns mockk()
         every { exposureWindowRiskCalculationConfigMapper.map(any()) } returns mockk()
+
+        appConfig171.exists() shouldBe true
+        appConfig180.exists() shouldBe true
     }
 
     @AfterEach
@@ -57,6 +68,22 @@ class ConfigParserTest : BaseTest() {
         }
     }
 
+    @Test
+    fun `parsing the 1_7_1 config throws exception`() {
+        // We don't want to use the 1.7.x config as fallback once we are on 1.8.x
+        // If parsing cached config data fails, we will fallback to the default config of 1.8.x
+        shouldThrow<InvalidProtocolBufferException> {
+            createInstance().parse(appConfig171.readBytes())
+        }
+    }
+
+    @Test
+    fun `parsing the 1_8_0 config does not throw an exception`() {
+        createInstance().parse(appConfig180.readBytes()).apply {
+            rawConfig shouldNotBe null
+        }
+    }
+
     companion object {
         private val APPCONFIG_RAW = (
             "081f101f1a0e0a0c0a0872657365727665641001220244452a061" +
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/DownloadDiagnosisKeysSettingsTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/DownloadDiagnosisKeysSettingsTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..44f67e089885700329b608a9d448f36ce2b8609f
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/DownloadDiagnosisKeysSettingsTest.kt
@@ -0,0 +1,79 @@
+package de.rki.coronawarnapp.diagnosiskeys
+
+import android.content.Context
+import androidx.core.content.edit
+import de.rki.coronawarnapp.diagnosiskeys.download.DownloadDiagnosisKeysSettings
+import de.rki.coronawarnapp.diagnosiskeys.download.isUpdateToEnfV2
+import de.rki.coronawarnapp.diagnosiskeys.download.updateLastVersionCodeToCurrent
+import de.rki.coronawarnapp.environment.BuildConfigWrap
+import de.rki.coronawarnapp.util.serialization.SerializationModule
+import io.kotest.matchers.shouldBe
+import io.mockk.MockKAnnotations
+import io.mockk.clearAllMocks
+import io.mockk.every
+import io.mockk.impl.annotations.MockK
+import io.mockk.mockkObject
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import testhelpers.BaseTest
+import testhelpers.preferences.MockSharedPreferences
+
+class DownloadDiagnosisKeysSettingsTest : BaseTest() {
+    @MockK lateinit var context: Context
+    lateinit var preferences: MockSharedPreferences
+
+    private val baseGson = SerializationModule().baseGson()
+
+    @BeforeEach
+    fun setup() {
+        MockKAnnotations.init(this)
+        preferences = MockSharedPreferences()
+        every { context.getSharedPreferences("keysync_localdata", Context.MODE_PRIVATE) } returns preferences
+
+        mockkObject(BuildConfigWrap)
+    }
+
+    @AfterEach
+    fun tearDown() {
+        clearAllMocks()
+    }
+
+    fun createInstance() = DownloadDiagnosisKeysSettings(
+        context = context,
+        gson = baseGson
+    )
+
+    @Test
+    fun `lastVersionCode default values`() {
+        val instance = createInstance()
+        instance.lastVersionCode shouldBe -1L
+        instance.isUpdateToEnfV2 shouldBe true
+    }
+
+    @Test
+    fun `lastVersionCode on 1_8_x`() {
+        preferences.edit {
+            putLong("download.task.last.versionCode", 1080000)
+        }
+        val instance = createInstance()
+        instance.lastVersionCode shouldBe 1080000L
+        instance.isUpdateToEnfV2 shouldBe false
+    }
+
+    @Test
+    fun `update the last versionCode`() {
+        val instance = createInstance()
+        instance.lastVersionCode = 99
+        instance.isUpdateToEnfV2 shouldBe true
+        instance.lastVersionCode shouldBe 99
+        instance.isUpdateToEnfV2 shouldBe true
+
+        every { BuildConfigWrap.VERSION_CODE } returns 1080000
+
+        instance.updateLastVersionCodeToCurrent()
+        instance.lastVersionCode shouldBe 1080000
+        instance.isUpdateToEnfV2 shouldBe false
+        preferences.dataMapPeek["download.task.last.versionCode"] shouldBe 1080000
+    }
+}
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/DownloadDiagnosisKeysTaskTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/DownloadDiagnosisKeysTaskTest.kt
index 4aec1691f060b27ae4a8ff466967840a4c80475c..666493af418fd8f43791eff09ad33f5807743b95 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/DownloadDiagnosisKeysTaskTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/DownloadDiagnosisKeysTaskTest.kt
@@ -1,15 +1,34 @@
 package de.rki.coronawarnapp.diagnosiskeys.download
 
+import com.google.android.gms.nearby.exposurenotification.DiagnosisKeysDataMapping
 import de.rki.coronawarnapp.appconfig.AppConfigProvider
+import de.rki.coronawarnapp.appconfig.ConfigData
+import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKey
+import de.rki.coronawarnapp.environment.BuildConfigWrap
 import de.rki.coronawarnapp.environment.EnvironmentSetup
 import de.rki.coronawarnapp.nearby.ENFClient
+import de.rki.coronawarnapp.nearby.modules.detectiontracker.TrackedExposureDetection
 import de.rki.coronawarnapp.util.TimeStamper
 import io.mockk.MockKAnnotations
+import io.mockk.Runs
 import io.mockk.clearAllMocks
+import io.mockk.coEvery
+import io.mockk.coVerify
+import io.mockk.coVerifySequence
+import io.mockk.every
 import io.mockk.impl.annotations.MockK
+import io.mockk.just
+import io.mockk.mockkObject
+import io.mockk.verify
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.runBlockingTest
+import org.joda.time.Duration
+import org.joda.time.Instant
 import org.junit.jupiter.api.AfterEach
 import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
 import testhelpers.BaseTest
+import java.io.File
 
 class DownloadDiagnosisKeysTaskTest : BaseTest() {
 
@@ -18,10 +37,60 @@ class DownloadDiagnosisKeysTaskTest : BaseTest() {
     @MockK lateinit var appConfigProvider: AppConfigProvider
     @MockK lateinit var keyPackageSyncTool: KeyPackageSyncTool
     @MockK lateinit var timeStamper: TimeStamper
+    @MockK lateinit var downloadSettings: DownloadDiagnosisKeysSettings
+
+    @MockK lateinit var appConfig: ConfigData
+    @MockK lateinit var syncResult: KeyPackageSyncTool.Result
+    @MockK lateinit var diagnosisKeyDataMapping: DiagnosisKeysDataMapping
+
+    @MockK lateinit var availableKey1: CachedKey
+    @MockK lateinit var newKey1: CachedKey
+
+    @MockK lateinit var latestTrackedDetection: TrackedExposureDetection
 
     @BeforeEach
     fun setup() {
         MockKAnnotations.init(this)
+
+        mockkObject(BuildConfigWrap)
+        every { BuildConfigWrap.VERSION_CODE } returns 1080005
+
+        availableKey1.apply {
+            every { path } returns File("availableKey1")
+        }
+        newKey1.apply {
+            every { path } returns File("newKey1")
+        }
+
+        appConfig.apply {
+            every { maxExposureDetectionsPerUTCDay } returns 5
+            every { minTimeBetweenDetections } returns Duration.standardHours(24 / 6)
+            every { diagnosisKeysDataMapping } returns diagnosisKeyDataMapping
+        }
+        coEvery { appConfigProvider.getAppConfig() } returns appConfig
+
+        downloadSettings.apply {
+            every { lastVersionCode } returns 1080000
+            every { lastVersionCode = any() } just Runs
+        }
+
+        every { enfClient.isTracingEnabled } returns flowOf(true)
+        every { timeStamper.nowUTC } returns Instant.EPOCH.plus(Duration.standardHours(5))
+        every { environmentSetup.useEuropeKeyPackageFiles } returns true
+
+        coEvery { keyPackageSyncTool.syncKeyFiles(any()) } returns syncResult.apply {
+            every { availableKeys } returns listOf(availableKey1)
+            every { newKeys } returns listOf(newKey1)
+        }
+
+        enfClient.apply {
+            latestTrackedDetection.apply {
+                every { startedAt } returns Instant.EPOCH
+                every { isSuccessful } returns true
+            }
+            coEvery { latestTrackedExposureDetection() } returns flowOf(listOf(latestTrackedDetection))
+            coEvery { provideDiagnosisKeys(any(), any()) } returns true
+        }
     }
 
     @AfterEach
@@ -34,6 +103,102 @@ class DownloadDiagnosisKeysTaskTest : BaseTest() {
         environmentSetup = environmentSetup,
         appConfigProvider = appConfigProvider,
         keyPackageSyncTool = keyPackageSyncTool,
-        timeStamper = timeStamper
+        timeStamper = timeStamper,
+        settings = downloadSettings
     )
+
+    @Test
+    fun `enf v1 to v2 change flag is checked and set`() = runBlockingTest {
+        every { downloadSettings.lastVersionCode } returns -1L
+
+        val task = createInstance()
+
+        task.run(DownloadDiagnosisKeysTask.Arguments())
+
+        coVerifySequence {
+            enfClient.isTracingEnabled
+            enfClient.latestTrackedExposureDetection()
+            enfClient.provideDiagnosisKeys(any(), any())
+        }
+        verify(exactly = 0) {
+            appConfig.minTimeBetweenDetections
+            syncResult.newKeys
+        }
+    }
+
+    @Test
+    fun `normal execution on first run`() = runBlockingTest {
+        val task = createInstance()
+
+        task.run(DownloadDiagnosisKeysTask.Arguments())
+
+        coVerifySequence {
+            enfClient.isTracingEnabled
+            enfClient.latestTrackedExposureDetection()
+            enfClient.provideDiagnosisKeys(any(), any())
+        }
+    }
+
+    @Test
+    fun `execution is skipped if last detection was recent via`() = runBlockingTest {
+        // Last detection was at T+2h
+        every { timeStamper.nowUTC } returns Instant.EPOCH.plus(Duration.standardHours(2))
+
+        createInstance().run(DownloadDiagnosisKeysTask.Arguments())
+
+        coVerifySequence {
+            enfClient.isTracingEnabled
+            enfClient.latestTrackedExposureDetection()
+        }
+
+        coVerify(exactly = 0) {
+            enfClient.provideDiagnosisKeys(any(), any())
+        }
+    }
+
+    @Test
+    fun `wasLastDetectionPerformedRecently honors paramters from config`() = runBlockingTest {
+        every { timeStamper.nowUTC } returns Instant.EPOCH.plus(Duration.standardHours(4))
+
+        createInstance().run(DownloadDiagnosisKeysTask.Arguments())
+
+        coVerifySequence {
+            enfClient.isTracingEnabled
+            enfClient.latestTrackedExposureDetection()
+            enfClient.provideDiagnosisKeys(any(), any())
+        }
+    }
+
+    @Test
+    fun `hasRecentDetectionAndNoNewFiles checks for new files`() = runBlockingTest {
+        every { timeStamper.nowUTC } returns Instant.EPOCH.plus(Duration.standardHours(4))
+
+        every { syncResult.newKeys } returns emptyList()
+
+        createInstance().run(DownloadDiagnosisKeysTask.Arguments())
+
+        coVerifySequence {
+            enfClient.isTracingEnabled
+            enfClient.latestTrackedExposureDetection()
+        }
+
+        coVerify(exactly = 0) {
+            enfClient.provideDiagnosisKeys(any(), any())
+        }
+    }
+
+    @Test
+    fun `hasRecentDetectionAndNoNewFiles ignores amount of files if we didn't update for a day`() = runBlockingTest {
+        every { timeStamper.nowUTC } returns Instant.EPOCH.plus(Duration.standardHours(25))
+
+        every { syncResult.newKeys } returns emptyList()
+
+        createInstance().run(DownloadDiagnosisKeysTask.Arguments())
+
+        coVerifySequence {
+            enfClient.isTracingEnabled
+            enfClient.latestTrackedExposureDetection()
+            enfClient.provideDiagnosisKeys(any(), any())
+        }
+    }
 }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/KeyPackageSyncToolTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/KeyPackageSyncToolTest.kt
index 4579828228e565c51d5e07f3738ba8ca657e9b00..18a42f38981624f677ba2feefab59801f98bb30c 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/KeyPackageSyncToolTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/KeyPackageSyncToolTest.kt
@@ -35,19 +35,19 @@ class KeyPackageSyncToolTest : BaseIOTest() {
     @MockK lateinit var keyCache: KeyCacheRepository
     @MockK lateinit var dayPackageSyncTool: DayPackageSyncTool
     @MockK lateinit var hourPackageSyncTool: HourPackageSyncTool
-    @MockK lateinit var syncSettings: KeyPackageSyncSettings
+    @MockK lateinit var syncSettings: DownloadDiagnosisKeysSettings
     @MockK lateinit var timeStamper: TimeStamper
     @MockK lateinit var networkStateProvider: NetworkStateProvider
     @MockK lateinit var networkState: NetworkStateProvider.State
-    private val lastDownloadDays: FlowPreference<KeyPackageSyncSettings.LastDownload?> = mockFlowPreference(
-        KeyPackageSyncSettings.LastDownload(
+    private val lastDownloadDays: FlowPreference<DownloadDiagnosisKeysSettings.LastDownload?> = mockFlowPreference(
+        DownloadDiagnosisKeysSettings.LastDownload(
             startedAt = Instant.EPOCH,
             finishedAt = Instant.EPOCH,
             successful = true
         )
     )
-    private val lastDownloadHours: FlowPreference<KeyPackageSyncSettings.LastDownload?> = mockFlowPreference(
-        KeyPackageSyncSettings.LastDownload(
+    private val lastDownloadHours: FlowPreference<DownloadDiagnosisKeysSettings.LastDownload?> = mockFlowPreference(
+        DownloadDiagnosisKeysSettings.LastDownload(
             startedAt = Instant.EPOCH,
             finishedAt = Instant.EPOCH,
             successful = true
@@ -202,14 +202,14 @@ class KeyPackageSyncToolTest : BaseIOTest() {
     @Test
     fun `failed last download causes force sync`() = runBlockingTest {
         lastDownloadDays.update {
-            KeyPackageSyncSettings.LastDownload(
+            DownloadDiagnosisKeysSettings.LastDownload(
                 startedAt = Instant.EPOCH,
                 finishedAt = Instant.EPOCH,
                 successful = false
             )
         }
         lastDownloadHours.update {
-            KeyPackageSyncSettings.LastDownload(
+            DownloadDiagnosisKeysSettings.LastDownload(
                 startedAt = Instant.EPOCH,
                 finishedAt = Instant.EPOCH,
                 successful = false
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/BaseRiskLevelStorageTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/BaseRiskLevelStorageTest.kt
index 8e9fd7d52bcb1d29a2e35bfe010fc7a053bd10dc..c6b172de4f6454dc7da0688aaa1776131ed90fdc 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/BaseRiskLevelStorageTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/BaseRiskLevelStorageTest.kt
@@ -50,7 +50,7 @@ class BaseRiskLevelStorageTest : BaseTest() {
         every { database.exposureWindows() } returns exposureWindowTables
         every { database.clearAllTables() } just Runs
 
-        every { riskLevelResultMigrator.getLegacyResults() } returns emptyList()
+        coEvery { riskLevelResultMigrator.getLegacyResults() } returns emptyList()
 
         every { riskResultTables.allEntries() } returns emptyFlow()
         coEvery { riskResultTables.insertEntry(any()) } just Runs
@@ -124,7 +124,7 @@ class BaseRiskLevelStorageTest : BaseTest() {
 
     @Test
     fun `if no risk level results are available we try to get legacy results`() {
-        every { riskLevelResultMigrator.getLegacyResults() } returns listOf(mockk(), mockk())
+        coEvery { riskLevelResultMigrator.getLegacyResults() } returns listOf(mockk(), mockk())
         every { riskResultTables.allEntries() } returns flowOf(emptyList())
         every { exposureWindowTables.allEntries() } returns flowOf(emptyList())
 
@@ -132,7 +132,7 @@ class BaseRiskLevelStorageTest : BaseTest() {
             val instance = createInstance()
             instance.riskLevelResults.first().size shouldBe 2
 
-            verify { riskLevelResultMigrator.getLegacyResults() }
+            coVerify { riskLevelResultMigrator.getLegacyResults() }
         }
     }
 
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/legacy/RiskLevelResultMigratorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/legacy/RiskLevelResultMigratorTest.kt
index 453bde1aa8e43131120df75ff2854a59eca99c08..3b95ea47cd3b7e0de90976cd3eb853be85c48d65 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/legacy/RiskLevelResultMigratorTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/storage/legacy/RiskLevelResultMigratorTest.kt
@@ -1,5 +1,6 @@
 package de.rki.coronawarnapp.risk.storage.legacy
 
+import android.content.Context
 import androidx.core.content.edit
 import de.rki.coronawarnapp.risk.RiskState
 import de.rki.coronawarnapp.util.TimeStamper
@@ -8,6 +9,7 @@ import io.mockk.MockKAnnotations
 import io.mockk.clearAllMocks
 import io.mockk.every
 import io.mockk.impl.annotations.MockK
+import kotlinx.coroutines.runBlocking
 import org.joda.time.Instant
 import org.junit.jupiter.api.AfterEach
 import org.junit.jupiter.api.BeforeEach
@@ -18,6 +20,7 @@ import testhelpers.preferences.MockSharedPreferences
 class RiskLevelResultMigratorTest : BaseTest() {
 
     @MockK lateinit var timeStamper: TimeStamper
+    @MockK lateinit var context: Context
     private val mockPreferences = MockSharedPreferences()
 
     @BeforeEach
@@ -34,11 +37,12 @@ class RiskLevelResultMigratorTest : BaseTest() {
 
     fun createInstance() = RiskLevelResultMigrator(
         timeStamper = timeStamper,
-        encryptedPreferences = { mockPreferences }
+        encryptedPreferences = { mockPreferences },
+        context = context
     )
 
     @Test
-    fun `normal case with full values`() {
+    fun `normal case with full values`() = runBlocking {
         mockPreferences.edit {
             putInt("preference_risk_level_score", MigrationRiskLevelConstants.INCREASED_RISK)
             putInt("preference_risk_level_score_successful", MigrationRiskLevelConstants.LOW_LEVEL_RISK)
@@ -58,13 +62,13 @@ class RiskLevelResultMigratorTest : BaseTest() {
     }
 
     @Test
-    fun `empty list if no previous data was available`() {
+    fun `empty list if no previous data was available`() = runBlocking {
         mockPreferences.dataMapPeek.isEmpty() shouldBe true
         createInstance().getLegacyResults() shouldBe emptyList()
     }
 
     @Test
-    fun `if no timestamp is available we use the current time`() {
+    fun `if no timestamp is available we use the current time`() = runBlocking {
         mockPreferences.edit {
             putInt("preference_risk_level_score", MigrationRiskLevelConstants.INCREASED_RISK)
             putInt("preference_risk_level_score_successful", MigrationRiskLevelConstants.LOW_LEVEL_RISK)
@@ -83,7 +87,7 @@ class RiskLevelResultMigratorTest : BaseTest() {
     }
 
     @Test
-    fun `last successful is null`() {
+    fun `last successful is null`() = runBlocking {
         mockPreferences.edit {
             putInt("preference_risk_level_score_successful", MigrationRiskLevelConstants.INCREASED_RISK)
         }
@@ -98,7 +102,7 @@ class RiskLevelResultMigratorTest : BaseTest() {
     }
 
     @Test
-    fun `last successfully calculated is null`() {
+    fun `last successfully calculated is null`() = runBlocking {
         mockPreferences.edit {
             putInt("preference_risk_level_score", MigrationRiskLevelConstants.INCREASED_RISK)
             putLong("preference_timestamp_risk_level_calculation", 1234567890L)
@@ -114,7 +118,7 @@ class RiskLevelResultMigratorTest : BaseTest() {
     }
 
     @Test
-    fun `exceptions are handled gracefully`() {
+    fun `exceptions are handled gracefully`() = runBlocking {
         mockPreferences.edit {
             putInt("preference_risk_level_score", MigrationRiskLevelConstants.INCREASED_RISK)
         }
diff --git a/Corona-Warn-App/src/test/resources/appconfig_1_7_1.bin b/Corona-Warn-App/src/test/resources/appconfig_1_7_1.bin
new file mode 100644
index 0000000000000000000000000000000000000000..372f95657fc5b88c39d4f2baac77cec169e20ba6
Binary files /dev/null and b/Corona-Warn-App/src/test/resources/appconfig_1_7_1.bin differ
diff --git a/Corona-Warn-App/src/test/resources/appconfig_1_8_0.bin b/Corona-Warn-App/src/test/resources/appconfig_1_8_0.bin
new file mode 100644
index 0000000000000000000000000000000000000000..8b4b13ce8bfb73231da85ec22602b208ece7f226
Binary files /dev/null and b/Corona-Warn-App/src/test/resources/appconfig_1_8_0.bin differ
diff --git a/Corona-Warn-App/src/testDevice/java/de/rki/coronawarnapp/test/risk/storage/DefaultRiskLevelStorageTest.kt b/Corona-Warn-App/src/testDevice/java/de/rki/coronawarnapp/test/risk/storage/DefaultRiskLevelStorageTest.kt
index 09b586353b1c3d5f3e1b28887814710876fc388e..5085f60d184d9cacd3706cc50c32c5708dd5f8f0 100644
--- a/Corona-Warn-App/src/testDevice/java/de/rki/coronawarnapp/test/risk/storage/DefaultRiskLevelStorageTest.kt
+++ b/Corona-Warn-App/src/testDevice/java/de/rki/coronawarnapp/test/risk/storage/DefaultRiskLevelStorageTest.kt
@@ -75,7 +75,7 @@ class DefaultRiskLevelStorageTest : BaseTest() {
         every { database.exposureWindows() } returns exposureWindowTables
         every { database.clearAllTables() } just Runs
 
-        every { riskLevelResultMigrator.getLegacyResults() } returns emptyList()
+        coEvery { riskLevelResultMigrator.getLegacyResults() } returns emptyList()
 
         every { riskResultTables.allEntries() } returns flowOf(listOf(testRiskLevelResultDao))
         coEvery { riskResultTables.insertEntry(any()) } just Runs
diff --git a/Corona-Warn-App/src/testDeviceForTesters/java/de/rki/coronawarnapp/test/risk/storage/DefaultRiskLevelStorageTest.kt b/Corona-Warn-App/src/testDeviceForTesters/java/de/rki/coronawarnapp/test/risk/storage/DefaultRiskLevelStorageTest.kt
index 396eee55921cc00a270a2aacbaba4b20fbe18372..85da20abc73c054d9c9442c9f7f3c0e94fbf3c95 100644
--- a/Corona-Warn-App/src/testDeviceForTesters/java/de/rki/coronawarnapp/test/risk/storage/DefaultRiskLevelStorageTest.kt
+++ b/Corona-Warn-App/src/testDeviceForTesters/java/de/rki/coronawarnapp/test/risk/storage/DefaultRiskLevelStorageTest.kt
@@ -75,7 +75,7 @@ class DefaultRiskLevelStorageTest : BaseTest() {
         every { database.exposureWindows() } returns exposureWindowTables
         every { database.clearAllTables() } just Runs
 
-        every { riskLevelResultMigrator.getLegacyResults() } returns emptyList()
+        coEvery { riskLevelResultMigrator.getLegacyResults() } returns emptyList()
 
         every { riskResultTables.allEntries() } returns flowOf(listOf(testRiskLevelResultDao))
         coEvery { riskResultTables.insertEntry(any()) } just Runs