diff --git a/cadence/tests/auto_borrow_behavior_test.cdc b/cadence/tests/auto_borrow_behavior_test.cdc index 6e9817d1..e3331286 100644 --- a/cadence/tests/auto_borrow_behavior_test.cdc +++ b/cadence/tests/auto_borrow_behavior_test.cdc @@ -75,18 +75,24 @@ fun testAutoBorrowBehaviorWithTargetHealth() { message: "Expected MOET to be in Debit (borrowed) state") // Verify the amount is approximately what we calculated (within 0.01 tolerance) - Test.assert(moetBalance >= expectedDebt - 0.01 && moetBalance <= expectedDebt + 0.01, - message: "Expected MOET debt to be approximately \(expectedDebt), but got \(moetBalance)") + Test.assert( + equalWithinVariance(expectedDebt, moetBalance, 0.01), + message: "Expected MOET debt to be approximately \(expectedDebt), but got \(moetBalance)", + ) // Verify position health is at target let health = getPositionHealth(pid: 0, beFailed: false) - Test.assert(equalWithinVariance(INT_TARGET_HEALTH, health), - message: "Expected health to be \(INT_TARGET_HEALTH), but got \(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) let userMoetBalance = getBalance(address: user.address, vaultPublicPath: MOET.VaultPublicPath)! - Test.assert(userMoetBalance >= expectedDebt - 0.01 && userMoetBalance <= expectedDebt + 0.01, - message: "Expected user MOET Vault balance to be approximately \(expectedDebt), but got \(userMoetBalance)") + Test.assert( + equalWithinVariance(expectedDebt, userMoetBalance, 0.01), + message: "Expected user MOET Vault balance to be approximately \(expectedDebt), but got \(userMoetBalance)", + ) } access(all) diff --git a/cadence/tests/compute_available_withdrawal_test.cdc b/cadence/tests/compute_available_withdrawal_test.cdc index efe3614e..841e727a 100644 --- a/cadence/tests/compute_available_withdrawal_test.cdc +++ b/cadence/tests/compute_available_withdrawal_test.cdc @@ -86,7 +86,7 @@ fun test_atTargetHealth_nothingAvailable() { depositAmount: 0.0, beFailed: false ) - Test.assert(equalWithinVariance(0.0, availableMOET), + Test.assert(equalWithinVariance(0.0, availableMOET, DEFAULT_UFIX_VARIANCE), message: "Expected 0 MOET available at target health, got \(availableMOET)") let availableFLOW = fundsAvailableAboveTargetHealthAfterDepositing( @@ -97,7 +97,7 @@ fun test_atTargetHealth_nothingAvailable() { depositAmount: 0.0, beFailed: false ) - Test.assert(equalWithinVariance(0.0, availableFLOW), + Test.assert(equalWithinVariance(0.0, availableFLOW, DEFAULT_UFIX_VARIANCE), message: "Expected 0 FLOW available at target health, got \(availableFLOW)") } @@ -130,7 +130,7 @@ fun test_noCreditInWithdrawToken_zerodebt_fullBorrowCapacity() { depositAmount: 0.0, beFailed: false ) - Test.assert(equalWithinVariance(expectedAvailable, actualAvailable), + Test.assert(equalWithinVariance(expectedAvailable, actualAvailable, DEFAULT_UFIX_VARIANCE), message: "Expected \(expectedAvailable) MOET available (zero-debt full capacity), got \(actualAvailable)") } @@ -158,7 +158,7 @@ fun test_creditInWithdrawToken_partialCollateralOnly() { // Confirm the borrow happened and health is at target let healthAtCreation = getPositionHealth(pid: pid, beFailed: false) - Test.assert(equalWithinVariance(UFix64(INT_TARGET_HEALTH), UFix64(healthAtCreation)), + Test.assert(equalWithinVariance(UFix64(INT_TARGET_HEALTH), UFix64(healthAtCreation), DEFAULT_UFIX_VARIANCE), message: "Expected health ≈ 1.3 after creation with push, got \(healthAtCreation)") // Increase FLOW price to 2.0 → more headroom above target @@ -180,7 +180,7 @@ fun test_creditInWithdrawToken_partialCollateralOnly() { depositAmount: 0.0, beFailed: false ) - Test.assert(equalWithinVariance(expectedAvailable, actualAvailable), + Test.assert(equalWithinVariance(expectedAvailable, actualAvailable, DEFAULT_UFIX_VARIANCE), message: "Expected \(expectedAvailable) FLOW available (partial collateral withdrawal), got \(actualAvailable)") } @@ -242,7 +242,7 @@ fun test_creditFlipsIntoDebt_availabilityExceedsCreditBalance() { depositAmount: 0.0, beFailed: false ) - Test.assert(equalWithinVariance(expectedAvailable, actualAvailable), + Test.assert(equalWithinVariance(expectedAvailable, actualAvailable, DEFAULT_UFIX_VARIANCE), message: "Expected \(expectedAvailable) FLOW available (credit→debt flip), got \(actualAvailable)") } 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 a582cf20..74571fda 100644 --- a/cadence/tests/insurance_collection_test.cdc +++ b/cadence/tests/insurance_collection_test.cdc @@ -536,16 +536,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) @@ -572,18 +565,10 @@ 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)") - + 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/interest_curve_advanced_test.cdc b/cadence/tests/interest_curve_advanced_test.cdc index c1005703..2ff71c9e 100644 --- a/cadence/tests/interest_curve_advanced_test.cdc +++ b/cadence/tests/interest_curve_advanced_test.cdc @@ -192,8 +192,10 @@ fun test_curve_change_mid_accrual_and_rate_segmentation() { // Expected: 6153.84615384 * (factor - 1) ≈ 8.42992491 MOET let expectedGrowth1: UFix64 = 8.42992491 let tolerance: UFix64 = 0.0001 // Precision to 0.0001 MOET - let diff1 = growth1 > expectedGrowth1 ? growth1 - expectedGrowth1 : expectedGrowth1 - growth1 - Test.assert(diff1 <= tolerance, message: "Phase 1 growth should be ~8.42992491. Actual: \(growth1)") + Test.assert( + equalWithinVariance(expectedGrowth1, growth1, tolerance), + message: "Phase 1 growth should be ~\(expectedGrowth1). Actual: \(growth1)", + ) // ------------------------------------------------------------------------- // STEP 7: Change Interest Rate to 15% APY (Phase 2 Configuration) @@ -230,8 +232,10 @@ fun test_curve_change_mid_accrual_and_rate_segmentation() { // Formula: perSecondRate = 1 + 0.15/31_557_600, factor = perSecondRate^864000 // Expected: 6162.27607875 * (factor - 1) ≈ 25.35912505 MOET let expectedGrowth2: UFix64 = 25.35912505 - let diff2 = growth2 > expectedGrowth2 ? growth2 - expectedGrowth2 : expectedGrowth2 - growth2 - Test.assert(diff2 <= tolerance, message: "Phase 2 growth should be ~25.35912505. Actual: \(growth2)") + Test.assert( + equalWithinVariance(expectedGrowth2, growth2, tolerance), + message: "Phase 2 growth should be ~\(expectedGrowth2). Actual: \(growth2)", + ) // ------------------------------------------------------------------------- // STEP 8: Change Interest Rate to 10% APY (Phase 3 Configuration) @@ -265,8 +269,10 @@ fun test_curve_change_mid_accrual_and_rate_segmentation() { // Formula: perSecondRate = 1 + 0.10/31_557_600, factor = perSecondRate^864000 // Expected: 6187.63520380 * (factor - 1) ≈ 16.96403378 MOET let expectedGrowth3: UFix64 = 16.96403378 - let diff3 = growth3 > expectedGrowth3 ? growth3 - expectedGrowth3 : expectedGrowth3 - growth3 - Test.assert(diff3 <= tolerance, message: "Phase 3 growth should be ~16.96403378. Actual: \(growth3)") + Test.assert( + equalWithinVariance(expectedGrowth3, growth3, tolerance), + message: "Phase 3 growth should be ~/(expectedGrowth3). Actual: \(growth3)", + ) // ========================================================================= // ASSERTIONS: Verify Rate Ratios Match Growth Ratios @@ -440,13 +446,13 @@ fun test_exact_compounding_verification_one_year() { log("Expected growth rate: \(expectedGrowthRate.toString())") Test.assert( - rateDiff <= tolerance, - message: "Growth rate should be ~0.105170918 (10.52% effective). Actual: \(actualGrowthRate)" + equalWithinVariance(expectedGrowthRate, actualGrowthRate, tolerance), + message: "Growth rate should be ~\(expectedGrowthRate) (10.52% effective). Actual: \(actualGrowthRate)" ) - Test.assert( - growthDiff <= tolerance, - message: "Growth should be ~652.54340074. Actual: \(actualGrowth)" + Test.assert( + equalWithinVariance(expectedGrowth, actualGrowth, tolerance), + message: "Growth should be ~\(expectedGrowth). Actual: \(actualGrowth)" ) log("=== TEST PASSED ===") @@ -654,7 +660,6 @@ fun test_credit_rate_changes_with_curve() { // Expected credit growth = creditBefore * 0.00625950922 ≈ 346.58 MOET let expectedCreditGrowthRate: UFix64 = 0.0062552 let expectedCreditGrowth: UFix64 = 346.58 - let tolerance: UFix64 = 0.0001 let rateDiff = creditGrowthRate > expectedCreditGrowthRate ? creditGrowthRate - expectedCreditGrowthRate @@ -671,13 +676,13 @@ fun test_credit_rate_changes_with_curve() { log("Rate difference: \(rateDiff.toString())") Test.assert( - growthDiff <= 0.01, - message: "Credit growth should be ~346.58. Actual: \(creditGrowth)" + equalWithinVariance(expectedCreditGrowth, creditGrowth, 0.01), + message: "Credit growth should be ~\(expectedCreditGrowth). Actual: \(creditGrowth)" ) Test.assert( - rateDiff <= tolerance, - message: "Credit growth rate should be ~0.0062552. Actual: \(creditGrowthRate)" + equalWithinVariance(expectedCreditGrowthRate, creditGrowthRate, 0.0001), + message: "Credit growth rate should be ~\(expectedCreditGrowthRate). Actual: \(creditGrowthRate)" ) log("=== TEST PASSED ===") diff --git a/cadence/tests/phase0_pure_math_test.cdc b/cadence/tests/phase0_pure_math_test.cdc index a76bab52..1b7bca6a 100644 --- a/cadence/tests/phase0_pure_math_test.cdc +++ b/cadence/tests/phase0_pure_math_test.cdc @@ -142,7 +142,7 @@ fun test_maxWithdraw_increasesDebtWhenNoCredit() { let deltaDebt = effColl / 1.3 let expected = deltaDebt * 0.8 Test.assert( - ufix128EqualWithinVariance(expected, max), + ufix128EqualWithinVariance(expected, max, DEFAULT_UFIX128_VARIANCE), message: "maxWithdraw debt increase mismatch" ) } diff --git a/cadence/tests/position_lifecycle_happy_test.cdc b/cadence/tests/position_lifecycle_happy_test.cdc index 7b502c8b..2512b9c6 100644 --- a/cadence/tests/position_lifecycle_happy_test.cdc +++ b/cadence/tests/position_lifecycle_happy_test.cdc @@ -64,13 +64,14 @@ fun testPositionLifecycleHappyPath() { // With 1000 Flow at 0.8 collateral factor = 800 effective collateral // Target health 1.3 means: effective debt = 800 / 1.3 ≈ 615.38 let expectedBorrowAmount = 615.38461538 - Test.assert(balanceAfterBorrow >= expectedBorrowAmount - 0.01 && - balanceAfterBorrow <= expectedBorrowAmount + 0.01, - message: "Expected MOET balance to be ~615.38, but got ".concat(balanceAfterBorrow.toString())) + Test.assert( + equalWithinVariance(expectedBorrowAmount, balanceAfterBorrow, 0.01), + message: "Expected MOET balance to be ~\(expectedBorrowAmount), but got \(balanceAfterBorrow.toString())", + ) // Check Flow balance before repayment let flowBalanceBefore = getBalance(address: user.address, vaultPublicPath: /public/flowTokenReceiver)! - log("Flow balance BEFORE repay: ".concat(flowBalanceBefore.toString())) + log("Flow balance BEFORE repay: \(flowBalanceBefore.toString())") // repay MOET and close position // The first position created has ID 0 @@ -87,6 +88,6 @@ fun testPositionLifecycleHappyPath() { Test.assertEqual(0.0, balanceAfterRepay) let flowBalanceAfter = getBalance(address: user.address, vaultPublicPath: /public/flowTokenReceiver)! - log("Flow balance after repay: ".concat(flowBalanceAfter.toString()).concat(" - Collateral successfully returned!")) + log("Flow balance after repay: \(flowBalanceAfter.toString()) - Collateral successfully returned!") Test.assert(flowBalanceAfter >= 999.99) // allow tiny rounding diff } diff --git a/cadence/tests/queued_deposits_integration_test.cdc b/cadence/tests/queued_deposits_integration_test.cdc index bb00a0be..abd61e8f 100644 --- a/cadence/tests/queued_deposits_integration_test.cdc +++ b/cadence/tests/queued_deposits_integration_test.cdc @@ -82,7 +82,7 @@ fun test_getQueuedDeposits_reportsQueuedBalance() { // We expect exactly one queued token type, and its balance should be the // 100 FLOW remainder that could not be accepted immediately. Test.assertEqual(UInt64(1), UInt64(queuedDeposits.length)) - equalWithinVariance(queuedDeposits[flowType]!, 100.0) + Test.assert(equalWithinVariance(100.0, queuedDeposits[flowType]!, DEFAULT_UFIX_VARIANCE)) } access(all) @@ -136,7 +136,7 @@ fun test_getQueuedDeposits_tracksPartialAndFullDrain() { // The new getter should initially report the full queued amount. var queuedDeposits = getQueuedDeposits(pid: 0, beFailed: false) - equalWithinVariance(queuedDeposits[flowType]!, 150.0) + Test.assert(equalWithinVariance(150.0, queuedDeposits[flowType]!, DEFAULT_UFIX_VARIANCE)) // After one hour, deposit capacity regenerates by the configured depositRate. // That takes the capacity cap from 100 to 200, so async processing can now accept @@ -150,7 +150,7 @@ fun test_getQueuedDeposits_tracksPartialAndFullDrain() { Test.expect(firstAsyncRes, Test.beSucceeded()) queuedDeposits = getQueuedDeposits(pid: 0, beFailed: false) - equalWithinVariance(queuedDeposits[flowType]!, 50.0) + Test.assert(equalWithinVariance(50.0, queuedDeposits[flowType]!, 0.05)) // Move forward another hour and run async processing again. The final 50 FLOW // should be deposited, leaving no queued entries behind. diff --git a/cadence/tests/rebalance_overcollateralised_test.cdc b/cadence/tests/rebalance_overcollateralised_test.cdc index 9e7d9ca6..7c3b060a 100644 --- a/cadence/tests/rebalance_overcollateralised_test.cdc +++ b/cadence/tests/rebalance_overcollateralised_test.cdc @@ -87,10 +87,12 @@ fun testRebalanceOvercollateralised() { } let tolerance: UFix64 = 0.01 - Test.assert((actualDebt >= expectedDebt - tolerance) && (actualDebt <= expectedDebt + tolerance)) + Test.assert(equalWithinVariance(expectedDebt, actualDebt, tolerance)) // Ensure the borrowed MOET after rebalance actually reached the user's Vault let userMoetBalance = getBalance(address: user.address, vaultPublicPath: MOET.VaultPublicPath)! - Test.assert(userMoetBalance >= expectedDebt - tolerance && userMoetBalance <= expectedDebt + tolerance, - message: "User MOET balance should reflect new debt (~".concat(expectedDebt.toString()).concat(") but was ").concat(userMoetBalance.toString())) + Test.assert( + equalWithinVariance(expectedDebt, userMoetBalance ,tolerance), + message: "User MOET balance should reflect new debt (~ \(expectedDebt.toString())) but was \(userMoetBalance.toString())", + ) } diff --git a/cadence/tests/rebalance_undercollateralised_test.cdc b/cadence/tests/rebalance_undercollateralised_test.cdc index 960b1cef..bab4d2d7 100644 --- a/cadence/tests/rebalance_undercollateralised_test.cdc +++ b/cadence/tests/rebalance_undercollateralised_test.cdc @@ -58,7 +58,7 @@ fun testRebalanceUndercollateralised() { let availableAfterPriceChange = getAvailableBalance(pid: 0, vaultIdentifier: MOET_TOKEN_IDENTIFIER, pullFromTopUpSource: true, beFailed: false) // After a price drop, the position becomes less healthy so the amount that is safely withdrawable should drop. - Test.assert(availableAfterPriceChange < availableBeforePriceChange, message: "Expected available balance to decrease after price drop (before: ".concat(availableBeforePriceChange.toString()).concat(", after: ").concat(availableAfterPriceChange.toString()).concat(")")) + Test.assert(availableAfterPriceChange < availableBeforePriceChange, message: "Expected available balance to decrease after price drop (before: \(availableBeforePriceChange.toString()), after: \(availableAfterPriceChange.toString()))") // Record the user's MOET balance before any pay-down so we can verify that the protocol actually // pulled the funds from the user during rebalance. @@ -92,23 +92,25 @@ fun testRebalanceUndercollateralised() { } } - let tolerance: UFix64 = 0.5 - Test.assert((actualDebt >= expectedDebt - tolerance) && (actualDebt <= expectedDebt + tolerance)) + let tolerance= 0.5 + Test.assert(equalWithinVariance(expectedDebt, actualDebt, tolerance)) // Ensure the user's MOET Vault balance decreased by roughly requiredPaydown. let userMoetBalanceAfter = getBalance(address: user.address, vaultPublicPath: MOET.VaultPublicPath)! let paidDown = userMoetBalanceBefore - userMoetBalanceAfter - Test.assert(paidDown >= requiredPaydown - tolerance && paidDown <= requiredPaydown + tolerance, - message: "User should have contributed ~".concat(requiredPaydown.toString()).concat(" MOET toward pay-down but actually contributed ").concat(paidDown.toString())) + Test.assert( + equalWithinVariance(paidDown, requiredPaydown, tolerance), + message: "User should have contributed ~ \(requiredPaydown.toString()) MOET toward pay-down but actually contributed \(paidDown.toString())" + ) - log("Health after price change: ".concat(healthAfterPriceChange.toString())) - log("Required paydown: ".concat(requiredPaydown.toString())) - log("Expected debt: ".concat(expectedDebt.toString())) - log("Actual debt: ".concat(actualDebt.toString())) + log("Health after price change: \(healthAfterPriceChange.toString())") + log("Required paydown: \(requiredPaydown.toString())") + log("Expected debt: \(expectedDebt.toString())") + log("Actual debt: \(actualDebt.toString())") // Ensure health is at least the minimum threshold (1.1) Test.assert(healthAfterRebalance >= INT_MIN_HEALTH, - message: "Health after rebalance should be at least the minimum \(INT_MIN_HEALTH) but was ".concat(healthAfterRebalance.toString())) + message: "Health after rebalance should be at least the minimum \(INT_MIN_HEALTH) but was \(healthAfterRebalance.toString())") } /// Verifies that rebalancing panics when the topUpSource cannot supply enough funds to 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 7f56069c..709df83b 100644 --- a/cadence/tests/stability_collection_test.cdc +++ b/cadence/tests/stability_collection_test.cdc @@ -375,17 +375,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) @@ -412,12 +404,10 @@ 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)") - - // acumulative stability fund must equal sum of both collections + 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) Test.assert(collected_phase2 > collected_phase1, message: "Phase 2 collection should exceed phase 1 due to higher rate") diff --git a/cadence/tests/test_helpers.cdc b/cadence/tests/test_helpers.cdc index 6608f224..44c93bd2 100644 --- a/cadence/tests/test_helpers.cdc +++ b/cadence/tests/test_helpers.cdc @@ -1026,28 +1026,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 --- */