From 8001167ef9392f7436534ae368af6f372434f973 Mon Sep 17 00:00:00 2001 From: UlyanaAndrukhiv Date: Tue, 10 Mar 2026 12:30:02 +0200 Subject: [PATCH] Refactored equalWithinVariance to use it with any custom variance --- cadence/tests/auto_borrow_behavior_test.cdc | 2 +- ...nds_available_above_target_health_test.cdc | 12 ++++---- .../funds_required_for_target_health_test.cdc | 14 ++++----- .../insurance_collection_formula_test.cdc | 13 ++------- cadence/tests/insurance_collection_test.cdc | 29 +++++-------------- cadence/tests/phase0_pure_math_test.cdc | 2 +- .../stability_collection_formula_test.cdc | 13 ++------- cadence/tests/stability_collection_test.cdc | 22 ++++---------- cadence/tests/test_helpers.cdc | 19 ++++++------ 9 files changed, 42 insertions(+), 84 deletions(-) diff --git a/cadence/tests/auto_borrow_behavior_test.cdc b/cadence/tests/auto_borrow_behavior_test.cdc index 6e9817d1..11f768f6 100644 --- a/cadence/tests/auto_borrow_behavior_test.cdc +++ b/cadence/tests/auto_borrow_behavior_test.cdc @@ -80,7 +80,7 @@ fun testAutoBorrowBehaviorWithTargetHealth() { // Verify position health is at target let health = getPositionHealth(pid: 0, beFailed: false) - Test.assert(equalWithinVariance(INT_TARGET_HEALTH, health), + Test.assert(equalWithinVariance(INT_TARGET_HEALTH, health, DEFAULT_UFIX128_VARIANCE), message: "Expected health to be \(INT_TARGET_HEALTH), but got \(health)") // Verify the user actually received the borrowed MOET in their Vault (draw-down sink) diff --git a/cadence/tests/funds_available_above_target_health_test.cdc b/cadence/tests/funds_available_above_target_health_test.cdc index e7bec820..5bb129e4 100644 --- a/cadence/tests/funds_available_above_target_health_test.cdc +++ b/cadence/tests/funds_available_above_target_health_test.cdc @@ -92,7 +92,7 @@ fun testFundsAvailableAboveTargetHealthAfterDepositingWithPushFromHealthy() { // assert expected starting point let balanceAfterBorrow = getBalance(address: userAccount.address, vaultPublicPath: MOET.VaultPublicPath)! let expectedBorrowAmount = (positionFundingAmount * flowCollateralFactor * flowStartPrice) / TARGET_HEALTH - Test.assert(equalWithinVariance(expectedBorrowAmount, balanceAfterBorrow), + Test.assert(equalWithinVariance(expectedBorrowAmount, balanceAfterBorrow, DEFAULT_UFIX_VARIANCE), message: "Expected MOET balance to be ~\(expectedBorrowAmount), but got \(balanceAfterBorrow)") let evts = Test.eventsOfType(Type()) @@ -113,10 +113,10 @@ fun testFundsAvailableAboveTargetHealthAfterDepositingWithPushFromHealthy() { } Test.assertEqual(positionFundingAmount, flowPositionBalance!.balance) - Test.assert(equalWithinVariance(expectedBorrowAmount, moetBalance!.balance), + Test.assert(equalWithinVariance(expectedBorrowAmount, moetBalance!.balance, DEFAULT_UFIX_VARIANCE), message: "Expected borrow amount to be \(expectedBorrowAmount), but got \(moetBalance!.balance)") - Test.assert(equalWithinVariance(INT_TARGET_HEALTH, health), + Test.assert(equalWithinVariance(INT_TARGET_HEALTH, health, DEFAULT_UFIX128_VARIANCE), message: "Expected health to be \(INT_TARGET_HEALTH), but got \(health)") log("[TEST] FLOW price set to \(flowStartPrice)") @@ -297,7 +297,7 @@ fun testFundsAvailableAboveTargetHealthAfterDepositingWithoutPushFromOvercollate log("[TEST] Depositing: \(depositAmount)") log("[TEST] Expected Available: \(expectedAvailable)") log("[TEST] Actual Available: \(actualAvailable)") - Test.assert(equalWithinVariance(expectedAvailable, actualAvailable), + Test.assert(equalWithinVariance(expectedAvailable, actualAvailable, DEFAULT_UFIX_VARIANCE), message: "Values are not equal within variance - expected: \(expectedAvailable), actual: \(actualAvailable)") log("..............................") @@ -315,7 +315,7 @@ fun testFundsAvailableAboveTargetHealthAfterDepositingWithoutPushFromOvercollate log("[TEST] Depositing: \(depositAmount)") log("[TEST] Expected Available: \(expectedAvailable)") log("[TEST] Actual Available: \(actualAvailable)") - Test.assert(equalWithinVariance(expectedAvailable, actualAvailable), + Test.assert(equalWithinVariance(expectedAvailable, actualAvailable, DEFAULT_UFIX_VARIANCE), message: "Values are not equal within variance - expected: \(expectedAvailable), actual: \(actualAvailable)") log("==============================") @@ -354,6 +354,6 @@ fun runFundsAvailableAboveTargetHealthAfterDepositing( log("[TEST] Depositing: \(depositAmount)") log("[TEST] Expected Available: \(expectedAvailable)") log("[TEST] Actual Available: \(actualAvailable)") - Test.assert(equalWithinVariance(expectedAvailable, actualAvailable), + Test.assert(equalWithinVariance(expectedAvailable, actualAvailable, DEFAULT_UFIX_VARIANCE), message: "Values are not equal within variance - expected: \(expectedAvailable), actual: \(actualAvailable)") } diff --git a/cadence/tests/funds_required_for_target_health_test.cdc b/cadence/tests/funds_required_for_target_health_test.cdc index 4d5dd58d..69611c28 100644 --- a/cadence/tests/funds_required_for_target_health_test.cdc +++ b/cadence/tests/funds_required_for_target_health_test.cdc @@ -87,7 +87,7 @@ fun testFundsRequiredForTargetHealthAfterWithdrawingWithPushFromHealthy() { // assert expected starting point startingDebt = getBalance(address: userAccount.address, vaultPublicPath: MOET.VaultPublicPath)! let expectedStartingDebt = (positionFundingAmount * flowCollateralFactor * flowStartPrice) / TARGET_HEALTH - Test.assert(equalWithinVariance(expectedStartingDebt, startingDebt), + Test.assert(equalWithinVariance(expectedStartingDebt, startingDebt, DEFAULT_UFIX_VARIANCE), message: "Expected MOET balance to be ~\(expectedStartingDebt), but got \(startingDebt)") var evts = Test.eventsOfType(Type()) @@ -102,7 +102,7 @@ fun testFundsRequiredForTargetHealthAfterWithdrawingWithPushFromHealthy() { Test.assertEqual(rebalancedEvt.amount, startingDebt) let health = getPositionHealth(pid: positionID, beFailed: false) - Test.assert(equalWithinVariance(INT_TARGET_HEALTH, health), + Test.assert(equalWithinVariance(INT_TARGET_HEALTH, health, DEFAULT_UFIX128_VARIANCE), message: "Expected health to be \(INT_TARGET_HEALTH), but got \(health)") log("[TEST] FLOW price set to \(flowStartPrice)") @@ -283,7 +283,7 @@ fun testFundsRequiredForTargetHealthAfterWithdrawingWithPushFromOvercollateraliz // assert expected starting point startingDebt = getBalance(address: userAccount.address, vaultPublicPath: MOET.VaultPublicPath)! let expectedStartingDebt = (positionFundingAmount * flowCollateralFactor * flowStartPrice) / TARGET_HEALTH - Test.assert(equalWithinVariance(expectedStartingDebt, startingDebt), + Test.assert(equalWithinVariance(expectedStartingDebt, startingDebt, DEFAULT_UFIX_VARIANCE), message: "Expected MOET balance to be ~\(expectedStartingDebt), but got \(startingDebt)") var evts = Test.eventsOfType(Type()) @@ -298,7 +298,7 @@ fun testFundsRequiredForTargetHealthAfterWithdrawingWithPushFromOvercollateraliz Test.assertEqual(rebalancedEvt.amount, startingDebt) let actualHealthBeforePriceIncrease = getPositionHealth(pid: positionID, beFailed: false) - Test.assert(equalWithinVariance(INT_TARGET_HEALTH, actualHealthBeforePriceIncrease), + Test.assert(equalWithinVariance(INT_TARGET_HEALTH, actualHealthBeforePriceIncrease, DEFAULT_UFIX128_VARIANCE), message: "Expected health to be \(INT_TARGET_HEALTH), but got \(actualHealthBeforePriceIncrease)") let priceIncrease = 0.25 @@ -438,7 +438,7 @@ fun testFundsRequiredForTargetHealthAfterWithdrawingWithPushFromUndercollaterali // assert expected starting point startingDebt = getBalance(address: userAccount.address, vaultPublicPath: MOET.VaultPublicPath)! let expectedStartingDebt = (positionFundingAmount * flowCollateralFactor * flowStartPrice) / TARGET_HEALTH - Test.assert(equalWithinVariance(expectedStartingDebt, startingDebt), + Test.assert(equalWithinVariance(expectedStartingDebt, startingDebt, DEFAULT_UFIX_VARIANCE), message: "Expected MOET balance to be ~\(expectedStartingDebt), but got \(startingDebt)") var evts = Test.eventsOfType(Type()) @@ -453,7 +453,7 @@ fun testFundsRequiredForTargetHealthAfterWithdrawingWithPushFromUndercollaterali Test.assertEqual(rebalancedEvt.amount, startingDebt) let actualHealthBeforePriceIncrease = getPositionHealth(pid: positionID, beFailed: false) - Test.assert(equalWithinVariance(INT_TARGET_HEALTH, actualHealthBeforePriceIncrease), + Test.assert(equalWithinVariance(INT_TARGET_HEALTH, actualHealthBeforePriceIncrease, DEFAULT_UFIX128_VARIANCE), message: "Expected health to be \(INT_TARGET_HEALTH), but got \(actualHealthBeforePriceIncrease)") let priceDecrease = 0.25 @@ -557,6 +557,6 @@ fun runFundsRequiredForTargetHealthAfterWithdrawing( log("[TEST] Withdrawing: \(withdrawAmount)") log("[TEST] Expected Required: \(ufixExpectedRequired)") log("[TEST] Actual Required: \(actualRequired)") - Test.assert(equalWithinVariance(ufixExpectedRequired, actualRequired), + Test.assert(equalWithinVariance(ufixExpectedRequired, actualRequired, DEFAULT_UFIX_VARIANCE), message: "Expected required funds to be \(ufixExpectedRequired), but got \(actualRequired)") } diff --git a/cadence/tests/insurance_collection_formula_test.cdc b/cadence/tests/insurance_collection_formula_test.cdc index 27c7cc39..254d4154 100644 --- a/cadence/tests/insurance_collection_formula_test.cdc +++ b/cadence/tests/insurance_collection_formula_test.cdc @@ -108,16 +108,7 @@ fun test_collectInsurance_success_fullAmount() { // With 10% annual debit rate over 1 year: debitIncome ≈ 615.38 * (1.10517091665 - 1) ≈ 64.72 // Insurance = debitIncome * 0.1 ≈ 6.472 MOET - // NOTE: - // We intentionally do not use `equalWithinVariance` with `defaultUFixVariance` here. - // The default variance is designed for deterministic math, but insurance collection - // depends on block timestamps, which can differ slightly between test runs. - // A larger, time-aware tolerance is required. - let tolerance = 0.001 let expectedCollectedAmount = 6.472 - let diff = expectedCollectedAmount > collectedAmount - ? expectedCollectedAmount - collectedAmount - : collectedAmount - expectedCollectedAmount - - Test.assert(diff < tolerance, message: "Insurance collected should be around \(expectedCollectedAmount) but current \(collectedAmount)") + Test.assert(equalWithinVariance(expectedCollectedAmount, collectedAmount, 0.001), + message: "Insurance collected should be around \(expectedCollectedAmount) but current \(collectedAmount)") } diff --git a/cadence/tests/insurance_collection_test.cdc b/cadence/tests/insurance_collection_test.cdc index 39a6fba3..be05b910 100644 --- a/cadence/tests/insurance_collection_test.cdc +++ b/cadence/tests/insurance_collection_test.cdc @@ -524,16 +524,9 @@ fun test_collectInsurance_midPeriodRateChange() { let reservesAfterPhase1 = getReserveBalance(vaultIdentifier: FLOW_TOKEN_IDENTIFIER) let collected_phase1 = reservesBefore_phase1 - reservesAfterPhase1 - // NOTE: - // We intentionally do not use `equalWithinVariance` with `defaultUFixVariance` here. - // The default variance is designed for deterministic math, but insurance collection - // depends on block timestamps, which can differ slightly between test runs. - // A larger, time-aware tolerance is required. - let tolerance = 0.00001 - var diff = expectedCollectedInsuranceAmountAfterPhase1 > insuranceAfterPhase1 - ? expectedCollectedInsuranceAmountAfterPhase1 - insuranceAfterPhase1 - : insuranceAfterPhase1 - expectedCollectedInsuranceAmountAfterPhase1 - Test.assert(diff < tolerance, message: "Insurance collected should be around \(expectedCollectedInsuranceAmountAfterPhase1) but current \(insuranceAfterPhase1)") + let expectedCollectedAmount = 6.472 + Test.assert(equalWithinVariance(expectedCollectedInsuranceAmountAfterPhase1, insuranceAfterPhase1, 0.00001), + message: "Insurance collected should be around \(expectedCollectedInsuranceAmountAfterPhase1) but current \(insuranceAfterPhase1)") Test.assertEqual(collected_phase1, insuranceAfterPhase1) let reservesBefore_phase2 = getReserveBalance(vaultIdentifier: FLOW_TOKEN_IDENTIFIER) @@ -559,19 +552,11 @@ fun test_collectInsurance_midPeriodRateChange() { let insuranceAfterPhase2 = getInsuranceFundBalance() let reservesAfterPhase2 = getReserveBalance(vaultIdentifier: FLOW_TOKEN_IDENTIFIER) - - // NOTE: - // We intentionally do not use `equalWithinVariance` with `defaultUFixVariance` here. - // The default variance is designed for deterministic math, but insurance collection - // depends on block timestamps, which can differ slightly between test runs. - // A larger, time-aware tolerance is required. - let expectedCollectedInsuranceAmount= expectedCollectedInsuranceAmountAfterPhase1 + expectedCollectedInsuranceAmountAfterPhase2 // 5.25854589 + 10.51709179 - diff = expectedCollectedInsuranceAmount > insuranceAfterPhase2 - ? expectedCollectedInsuranceAmount - insuranceAfterPhase2 - : insuranceAfterPhase2 - expectedCollectedInsuranceAmount - - Test.assert(diff < tolerance, message: "Insurance collected should be around \(expectedCollectedInsuranceAmount) but current \(insuranceAfterPhase2)") + let expectedCollectedInsuranceAmount= expectedCollectedInsuranceAmountAfterPhase1 + expectedCollectedInsuranceAmountAfterPhase2 // 5.25854589 + 10.51709179 + Test.assert(equalWithinVariance(expectedCollectedInsuranceAmount, insuranceAfterPhase2, 0.00001), + message: "Insurance collected should be around \(expectedCollectedInsuranceAmount) but current \(insuranceAfterPhase2)") + // acumulative insurance fund must equal sum of both collections let collected_phase2 = reservesBefore_phase2 - reservesAfterPhase2 Test.assertEqual(insuranceAfterPhase2, insuranceAfterPhase1 + collected_phase2) diff --git a/cadence/tests/phase0_pure_math_test.cdc b/cadence/tests/phase0_pure_math_test.cdc index 4b641fea..58727516 100644 --- a/cadence/tests/phase0_pure_math_test.cdc +++ b/cadence/tests/phase0_pure_math_test.cdc @@ -137,7 +137,7 @@ fun test_maxWithdraw_increasesDebtWhenNoCredit() { let effColl: UFix128 = 80.0 let expected = effColl / 1.3 Test.assert( - ufix128EqualWithinVariance(expected, max), + ufix128EqualWithinVariance(expected, max, DEFAULT_UFIX128_VARIANCE), message: "maxWithdraw debt increase mismatch" ) } diff --git a/cadence/tests/stability_collection_formula_test.cdc b/cadence/tests/stability_collection_formula_test.cdc index 00e8a0d6..ef5b72aa 100644 --- a/cadence/tests/stability_collection_formula_test.cdc +++ b/cadence/tests/stability_collection_formula_test.cdc @@ -102,16 +102,7 @@ fun test_collectStability_success_fullAmount() { // With 10% annual debit rate over 1 year: interestIncome ≈ 615.38 * (1.10517091665 - 1) ≈ 64.72 // Stability = interestIncome * 0.1 ≈ 6.472 MOET - // NOTE: - // We intentionally do not use `equalWithinVariance` with `defaultUFixVariance` here. - // The default variance is designed for deterministic math, but insurance collection - // depends on block timestamps, which can differ slightly between test runs. - // A larger, time-aware tolerance is required. - let tolerance = 0.001 let expectedCollectedAmount = 6.472 - let diff = expectedCollectedAmount > collectedAmount - ? expectedCollectedAmount - collectedAmount - : collectedAmount - expectedCollectedAmount - - Test.assert(diff < tolerance, message: "Stability collected should be around \(expectedCollectedAmount) but current \(collectedAmount)") + Test.assert(equalWithinVariance(expectedCollectedAmount, collectedAmount, 0.001), + message: "Stability collected should be around \(expectedCollectedAmount) but current \(collectedAmount)") } \ No newline at end of file diff --git a/cadence/tests/stability_collection_test.cdc b/cadence/tests/stability_collection_test.cdc index b1cbc268..bf2a2ce0 100644 --- a/cadence/tests/stability_collection_test.cdc +++ b/cadence/tests/stability_collection_test.cdc @@ -376,17 +376,9 @@ fun test_collectStability_midPeriodRateChange() { let reservesAfterPhase1 = getReserveBalance(vaultIdentifier: FLOW_TOKEN_IDENTIFIER) let collected_phase1 = reservesBefore_phase1 - reservesAfterPhase1 - // NOTE: - // We intentionally do not use `equalWithinVariance` with `defaultUFixVariance` here. - // The default variance is designed for deterministic math, but stability collection - // depends on block timestamps, which can differ slightly between test runs. - // A larger, time-aware tolerance is required. - let tolerance = 0.00001 - var diff = expectedStabilityAmountAfterPhase1 > stabilityAfterPhase1 - ? expectedStabilityAmountAfterPhase1 - stabilityAfterPhase1 - : stabilityAfterPhase1 - expectedStabilityAmountAfterPhase1 - Test.assert(diff < tolerance, message: "Stability collected should be around \(expectedStabilityAmountAfterPhase1) but current \(stabilityAfterPhase1)") - + Test.assert(equalWithinVariance(expectedStabilityAmountAfterPhase1, stabilityAfterPhase1, 0.00001), + message: "Stability collected should be around \(expectedStabilityAmountAfterPhase1) but current \(stabilityAfterPhase1)") + // stability fund balance must equal what was withdrawn from reserves // (no swap needed — stability is collected in the same token as the reserve) Test.assertEqual(collected_phase1, stabilityAfterPhase1) @@ -413,11 +405,9 @@ fun test_collectStability_midPeriodRateChange() { let reservesAfterPhase2 = getReserveBalance(vaultIdentifier: FLOW_TOKEN_IDENTIFIER) let expectedStabilityTotal = expectedStabilityAmountAfterPhase1 + expectedStabilityAmountAfterPhase2 // 2.62927294 + 10.51709179 - diff = expectedStabilityTotal > stabilityAfterPhase2 - ? expectedStabilityTotal - stabilityAfterPhase2 - : stabilityAfterPhase2 - expectedStabilityTotal - Test.assert(diff < tolerance, message: "Stability collected should be around \(expectedStabilityTotal) but current \(stabilityAfterPhase2)") - + Test.assert(equalWithinVariance(expectedStabilityTotal, stabilityAfterPhase2, 0.00001), + message: "Stability collected should be around \(expectedStabilityTotal) but current \(stabilityAfterPhase2)") + // cumulative stability fund must equal sum of both collections let collected_phase2 = reservesBefore_phase2 - reservesAfterPhase2 Test.assertEqual(stabilityAfterPhase2, stabilityAfterPhase1 + collected_phase2) diff --git a/cadence/tests/test_helpers.cdc b/cadence/tests/test_helpers.cdc index 19d43bc0..5472366e 100644 --- a/cadence/tests/test_helpers.cdc +++ b/cadence/tests/test_helpers.cdc @@ -881,28 +881,29 @@ fun withdrawReserve( /* --- Assertion Helpers --- */ -access(all) fun equalWithinVariance(_ expected: AnyStruct, _ actual: AnyStruct): Bool { +access(all) fun equalWithinVariance(_ expected: AnyStruct, _ actual: AnyStruct, _ variance: AnyStruct): Bool { let expectedType = expected.getType() let actualType = actual.getType() - if expectedType == Type() && actualType == Type() { - return ufixEqualWithinVariance(expected as! UFix64, actual as! UFix64) - } else if expectedType == Type() && actualType == Type() { - return ufix128EqualWithinVariance(expected as! UFix128, actual as! UFix128) + let varianceType = actual.getType() + if expectedType == Type() && actualType == Type() && varianceType == Type() { + return ufixEqualWithinVariance(expected as! UFix64, actual as! UFix64, variance as! UFix64) + } else if expectedType == Type() && actualType == Type() && varianceType == Type(){ + return ufix128EqualWithinVariance(expected as! UFix128, actual as! UFix128, variance as! UFix128) } panic("Expected and actual types do not match - expected: \(expectedType.identifier), actual: \(actualType.identifier)") } -access(all) fun ufixEqualWithinVariance(_ expected: UFix64, _ actual: UFix64): Bool { +access(all) fun ufixEqualWithinVariance(_ expected: UFix64, _ actual: UFix64, _ variance: UFix64): Bool { // return true if expected is within DEFAULT_UFIX_VARIANCE of actual, false otherwise and protect for underflow` let diff = Fix64(expected) - Fix64(actual) // take the absolute value of the difference without relying on .abs() let absDiff: UFix64 = diff < 0.0 ? UFix64(-1.0 * diff) : UFix64(diff) - return absDiff <= DEFAULT_UFIX_VARIANCE + return absDiff <= variance } -access(all) fun ufix128EqualWithinVariance(_ expected: UFix128, _ actual: UFix128): Bool { +access(all) fun ufix128EqualWithinVariance(_ expected: UFix128, _ actual: UFix128, _ variance: UFix128): Bool { let absDiff: UFix128 = expected >= actual ? expected - actual : actual - expected - return absDiff <= DEFAULT_UFIX128_VARIANCE + return absDiff <= variance } /* --- Balance & Timestamp Helpers --- */