Updated on 2026-08-14

This commit is contained in:
Tangem 2026-06-29 03:33:08 +04:00
parent 257351398c
commit ad6cb09999
2 changed files with 40 additions and 3 deletions

View file

@ -1343,7 +1343,6 @@ internal class SwapInteractorImpl @Inject constructor(
val dexFeeResultEither = if (fromStatus.isYieldSwapActive && fromStatus.currency is CryptoCurrency.Token) {
val network = (fromStatus.currency as CryptoCurrency.Token).network
val yieldModuleAddress = yieldModuleAddressProvider.getOrFetch(fromStatus.userWalletId, network)
// TODO YIELD [REDACTED_TASK_KEY]
dexSwapFeeCalculator.calculateYield(
fromSwapCurrencyStatus = fromStatus,
transaction = transaction,
@ -1992,7 +1991,11 @@ internal class SwapInteractorImpl @Inject constructor(
swapData = swapData,
provider = provider,
)
val isIntegratedApprovalNeeded = swapFeatureToggles.isSwapIntegratedApproveEnabled &&
val isYieldSwap = fromSwapCurrencyStatus.isYieldSwapActive &&
fromSwapCurrencyStatus.currency is CryptoCurrency.Token
val isIntegratedApprovalNeeded = !isYieldSwap &&
swapFeatureToggles.isSwapIntegratedApproveEnabled &&
allowanceInfo is AllowanceInfo.NotEnough &&
!hasIntegratedApprovalFallenBack(fromSwapCurrencyStatus, spenderAddress)
swapState.copy(
@ -2138,7 +2141,8 @@ internal class SwapInteractorImpl @Inject constructor(
requiredAmount = swapAmount.value,
).getOrNull() ?: return quotesLoadedState.copy(permissionState = PermissionDataState.Empty)
val isIntegratedApprovalNeeded = swapFeatureToggles.isSwapIntegratedApproveEnabled &&
val isIntegratedApprovalNeeded = !isYieldSwap &&
swapFeatureToggles.isSwapIntegratedApproveEnabled &&
allowanceInfo is AllowanceInfo.NotEnough &&
!hasIntegratedApprovalFallenBack(fromSwapCurrencyStatus, quoteModel.allowanceContract)
return quotesLoadedState.copy(

View file

@ -189,6 +189,38 @@ internal class SwapInteractorImplLoadDexSwapDataNoFeeTest : SwapInteractorImplTe
assertThat(state.permissionState).isEqualTo(PermissionDataState.Empty)
}
@Test
fun `GIVEN yield swap AND NotEnough allowance AND integrated active THEN permissionState is not integrated`() =
runTest {
// [REDACTED_TASK_KEY] / iOS parity: yield swaps must never use the integrated approve+swap path.
// The yield-module proxy allowance is granted at enrollment, so no in-flow approval is shown.
every { swapFeatureToggles.isSwapIntegratedApproveEnabled } returns true
every { swapFeatureToggles.isYieldSwapEnabled } returns true
coEvery { yieldModuleAddressProvider.getOrFetch(any(), any()) } returns YIELD_PROXY
coEvery { walletManagersFacade.isSwapSpenderAllowed(any(), any(), any()) } returns true
stubAllowance(AllowanceInfo.NotEnough(allowance = BigDecimal.ZERO, requiredAmount = BigDecimal.ONE))
val dexProvider = stubDexQuoteAndExchangeData()
val result = sut.findBestQuote(
fromSwapCurrencyStatus = buildSwapCurrencyStatus(
networkRawId = ethNetwork,
isCoin = false,
contractAddress = "0xToken",
amount = BigDecimal("10"),
yieldSupplyActive = true,
),
toSwapCurrencyStatus = buildSwapCurrencyStatus(networkRawId = ethNetwork),
providers = listOf(dexProvider),
amountToSwap = "1.0",
reduceBalanceBy = BigDecimal.ZERO,
)
val state = result[dexProvider] as SwapState.QuotesLoadedState
assertThat(state.permissionState)
.isNotInstanceOf(PermissionDataState.PermissionSettings::class.java)
assertThat(state.permissionState).isEqualTo(PermissionDataState.Empty)
}
@Test
fun `GIVEN NotEnough allowance AND integrated toggle OFF THEN does not reach loadDexSwapDataNoFee`() = runTest {
// With the integrated toggle off, NotEnough is not allowance-satisfied (requires Enough),
@ -290,5 +322,6 @@ internal class SwapInteractorImplLoadDexSwapDataNoFeeTest : SwapInteractorImplTe
private companion object {
const val SPENDER = "0xSpender"
const val YIELD_PROXY = "0xYieldProxy"
}
}