From 3eaa1badcb17d45aff6bbe50bba330458828a045 Mon Sep 17 00:00:00 2001 From: Alex <12097569+nialexsan@users.noreply.github.com> Date: Wed, 11 Feb 2026 21:48:06 -0500 Subject: [PATCH 1/6] update FlowActions ref --- FlowActions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FlowActions b/FlowActions index 0cd0fcc..f820beb 160000 --- a/FlowActions +++ b/FlowActions @@ -1 +1 @@ -Subproject commit 0cd0fcc94e63fcfc954ea98b5b8b30d3535011da +Subproject commit f820bebe6d81dc91bdf99c94acdac3333c88ef20 From cdb155cdda36658b424760b9c1fa7a5db6487624 Mon Sep 17 00:00:00 2001 From: Alex <12097569+nialexsan@users.noreply.github.com> Date: Wed, 11 Feb 2026 23:29:00 -0500 Subject: [PATCH 2/6] min balance threshold --- cadence/contracts/FlowALPv1.cdc | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/cadence/contracts/FlowALPv1.cdc b/cadence/contracts/FlowALPv1.cdc index 19696af..c02501b 100644 --- a/cadence/contracts/FlowALPv1.cdc +++ b/cadence/contracts/FlowALPv1.cdc @@ -383,13 +383,22 @@ access(all) contract FlowALPv1 { // so we just decrement the credit balance. let updatedBalance = trueBalance - amount - self.scaledBalance = FlowALPv1.trueBalanceToScaledBalance( - updatedBalance, - interestIndex: tokenState.creditInterestIndex - ) + // If the remaining balance is dust (below UFix64 precision threshold), + // sweep it to zero to prevent dust positions that would violate minimum + // balance requirements. This dust arises from UFix128->UFix64 rounding + // in availableBalance calculations. + if updatedBalance > 0.0 && updatedBalance < 0.00000010 { + self.scaledBalance = 0.0 + tokenState.decreaseCreditBalance(by: trueBalance) + } else { + self.scaledBalance = FlowALPv1.trueBalanceToScaledBalance( + updatedBalance, + interestIndex: tokenState.creditInterestIndex + ) - // Decrease the total credit balance for the token - tokenState.decreaseCreditBalance(by: amount) + // Decrease the total credit balance for the token + tokenState.decreaseCreditBalance(by: amount) + } } else { // The withdrawal is enough to push the position into debt, // so we switch to a debit position. @@ -2985,8 +2994,10 @@ access(all) contract FlowALPv1 { let remainingBalance = positionView.trueBalance(ofToken: type) // This is applied to both credit and debit balances, with the main goal being to avoid dust positions. + // Remaining balances below the UFix64 precision threshold (1e-8) are treated as effectively zero, + // as they arise from unavoidable UFix128->UFix64 rounding in availableBalance calculations. assert( - remainingBalance == 0.0 || self.positionSatisfiesMinimumBalance(type: type, balance: remainingBalance), + remainingBalance < 0.00000010 || self.positionSatisfiesMinimumBalance(type: type, balance: remainingBalance), message: "Withdrawal would leave position below minimum balance requirement of \(self.globalLedger[type]!.minimumTokenBalancePerPosition). Remaining balance would be \(remainingBalance)." ) From 6ef4a6e0d63b396332a219fa5a89f9440a251f68 Mon Sep 17 00:00:00 2001 From: Alex <12097569+nialexsan@users.noreply.github.com> Date: Thu, 12 Feb 2026 11:16:42 -0500 Subject: [PATCH 3/6] dust handler --- cadence/contracts/FlowALPv1.cdc | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/cadence/contracts/FlowALPv1.cdc b/cadence/contracts/FlowALPv1.cdc index c02501b..1e71a27 100644 --- a/cadence/contracts/FlowALPv1.cdc +++ b/cadence/contracts/FlowALPv1.cdc @@ -383,22 +383,13 @@ access(all) contract FlowALPv1 { // so we just decrement the credit balance. let updatedBalance = trueBalance - amount - // If the remaining balance is dust (below UFix64 precision threshold), - // sweep it to zero to prevent dust positions that would violate minimum - // balance requirements. This dust arises from UFix128->UFix64 rounding - // in availableBalance calculations. - if updatedBalance > 0.0 && updatedBalance < 0.00000010 { - self.scaledBalance = 0.0 - tokenState.decreaseCreditBalance(by: trueBalance) - } else { - self.scaledBalance = FlowALPv1.trueBalanceToScaledBalance( - updatedBalance, - interestIndex: tokenState.creditInterestIndex - ) + self.scaledBalance = FlowALPv1.trueBalanceToScaledBalance( + updatedBalance, + interestIndex: tokenState.creditInterestIndex + ) - // Decrease the total credit balance for the token - tokenState.decreaseCreditBalance(by: amount) - } + // Decrease the total credit balance for the token + tokenState.decreaseCreditBalance(by: amount) } else { // The withdrawal is enough to push the position into debt, // so we switch to a debit position. @@ -2994,10 +2985,11 @@ access(all) contract FlowALPv1 { let remainingBalance = positionView.trueBalance(ofToken: type) // This is applied to both credit and debit balances, with the main goal being to avoid dust positions. - // Remaining balances below the UFix64 precision threshold (1e-8) are treated as effectively zero, - // as they arise from unavoidable UFix128->UFix64 rounding in availableBalance calculations. + // Remaining balances below the dust threshold are treated as effectively zero. This dust arises + // from precision loss in health factor math (UFix128 arithmetic with prices, collateral/borrow + // factors) combined with UFix128->UFix64 rounding in availableBalance calculations. assert( - remainingBalance < 0.00000010 || self.positionSatisfiesMinimumBalance(type: type, balance: remainingBalance), + remainingBalance < 0.00000001 || self.positionSatisfiesMinimumBalance(type: type, balance: remainingBalance), message: "Withdrawal would leave position below minimum balance requirement of \(self.globalLedger[type]!.minimumTokenBalancePerPosition). Remaining balance would be \(remainingBalance)." ) From 74f939bcb795b03c733758d74c76f9eaa72455f5 Mon Sep 17 00:00:00 2001 From: Alex <12097569+nialexsan@users.noreply.github.com> Date: Thu, 12 Feb 2026 11:48:31 -0500 Subject: [PATCH 4/6] increase dust threshold --- cadence/contracts/FlowALPv1.cdc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cadence/contracts/FlowALPv1.cdc b/cadence/contracts/FlowALPv1.cdc index 1e71a27..d2f13d5 100644 --- a/cadence/contracts/FlowALPv1.cdc +++ b/cadence/contracts/FlowALPv1.cdc @@ -2989,7 +2989,7 @@ access(all) contract FlowALPv1 { // from precision loss in health factor math (UFix128 arithmetic with prices, collateral/borrow // factors) combined with UFix128->UFix64 rounding in availableBalance calculations. assert( - remainingBalance < 0.00000001 || self.positionSatisfiesMinimumBalance(type: type, balance: remainingBalance), + remainingBalance < 0.00000010 || self.positionSatisfiesMinimumBalance(type: type, balance: remainingBalance), message: "Withdrawal would leave position below minimum balance requirement of \(self.globalLedger[type]!.minimumTokenBalancePerPosition). Remaining balance would be \(remainingBalance)." ) From c40d87c7b1d63c34036d6d5e6571b65c854997a8 Mon Sep 17 00:00:00 2001 From: Alex <12097569+nialexsan@users.noreply.github.com> Date: Fri, 13 Feb 2026 11:20:31 -0500 Subject: [PATCH 5/6] increase dust threshold --- cadence/contracts/FlowALPv1.cdc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cadence/contracts/FlowALPv1.cdc b/cadence/contracts/FlowALPv1.cdc index d2f13d5..b052f50 100644 --- a/cadence/contracts/FlowALPv1.cdc +++ b/cadence/contracts/FlowALPv1.cdc @@ -2989,7 +2989,7 @@ access(all) contract FlowALPv1 { // from precision loss in health factor math (UFix128 arithmetic with prices, collateral/borrow // factors) combined with UFix128->UFix64 rounding in availableBalance calculations. assert( - remainingBalance < 0.00000010 || self.positionSatisfiesMinimumBalance(type: type, balance: remainingBalance), + remainingBalance < 0.00000300 || self.positionSatisfiesMinimumBalance(type: type, balance: remainingBalance), message: "Withdrawal would leave position below minimum balance requirement of \(self.globalLedger[type]!.minimumTokenBalancePerPosition). Remaining balance would be \(remainingBalance)." ) From 27eea854f1d125ee7613ad0749bc3435c267593f Mon Sep 17 00:00:00 2001 From: Alex <12097569+nialexsan@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:04:52 -0500 Subject: [PATCH 6/6] revert dust changes --- FlowActions | 2 +- cadence/contracts/FlowALPv1.cdc | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/FlowActions b/FlowActions index f820beb..527b2e5 160000 --- a/FlowActions +++ b/FlowActions @@ -1 +1 @@ -Subproject commit f820bebe6d81dc91bdf99c94acdac3333c88ef20 +Subproject commit 527b2e5b5aac4093ee3dc71ab47ff62bf3283733 diff --git a/cadence/contracts/FlowALPv1.cdc b/cadence/contracts/FlowALPv1.cdc index 3772ed2..ec6ed8b 100644 --- a/cadence/contracts/FlowALPv1.cdc +++ b/cadence/contracts/FlowALPv1.cdc @@ -3010,11 +3010,8 @@ access(all) contract FlowALPv1 { let remainingBalance = positionView.trueBalance(ofToken: type) // This is applied to both credit and debit balances, with the main goal being to avoid dust positions. - // Remaining balances below the dust threshold are treated as effectively zero. This dust arises - // from precision loss in health factor math (UFix128 arithmetic with prices, collateral/borrow - // factors) combined with UFix128->UFix64 rounding in availableBalance calculations. assert( - remainingBalance < 0.00000300 || self.positionSatisfiesMinimumBalance(type: type, balance: remainingBalance), + remainingBalance == 0.0 || self.positionSatisfiesMinimumBalance(type: type, balance: remainingBalance), message: "Withdrawal would leave position below minimum balance requirement of \(self.globalLedger[type]!.minimumTokenBalancePerPosition). Remaining balance would be \(remainingBalance)." )