@@ -141,6 +141,125 @@ fun testCannotBorrowSecondDebtType() {
141141 log (" \n === Test Complete: Debt Type Constraint Verified ===" )
142142}
143143
144+ /// Regression: exact debt repayment should clear debt-type constraints.
145+ /// After repaying FLOW debt to exactly zero, borrowing MOET as a new debt type should succeed.
146+ access (all )
147+ fun testExactRepayClearsDebtTypeConstraint () {
148+ Test .reset (to : snapshot )
149+ log (" \n === Test: Exact Repay Clears Debt Type Constraint ===\n " )
150+
151+ // Provide FLOW reserves for initial FLOW borrow.
152+ let flowProvider = Test .createAccount ()
153+ setupMoetVault (flowProvider , beFailed : false )
154+ transferFlowTokens (to : flowProvider , amount : 10_000.0 )
155+ grantBetaPoolParticipantAccess (PROTOCOL_ACCOUNT , flowProvider )
156+
157+ let createFlowPos = executeTransaction (
158+ " ../transactions/flow-alp/position/create_position.cdc" ,
159+ [5_000.0 , FLOW_VAULT_STORAGE_PATH , false ],
160+ flowProvider
161+ )
162+ Test .expect (createFlowPos , Test .beSucceeded ())
163+
164+ let user = Test .createAccount ()
165+ setupMoetVault (user , beFailed : false )
166+ setupDummyTokenVault (user )
167+ mintDummyToken (to : user , amount : 10_000.0 )
168+ grantBetaPoolParticipantAccess (PROTOCOL_ACCOUNT , user )
169+
170+ let createPosRes = executeTransaction (
171+ " ../transactions/flow-alp/position/create_position.cdc" ,
172+ [5_000.0 , DummyToken .VaultStoragePath , false ],
173+ user
174+ )
175+ Test .expect (createPosRes , Test .beSucceeded ())
176+
177+ let pid : UInt64 = 1
178+
179+ // Create FLOW debt, then repay exactly to zero.
180+ borrowFromPosition (
181+ signer : user ,
182+ positionId : pid ,
183+ tokenTypeIdentifier : FLOW_TOKEN_IDENTIFIER ,
184+ amount : 300.0 ,
185+ beFailed : false
186+ )
187+ depositToPosition (
188+ signer : user ,
189+ positionID : pid ,
190+ amount : 300.0 ,
191+ vaultStoragePath : FLOW_VAULT_STORAGE_PATH ,
192+ pushToDrawDownSink : false
193+ )
194+
195+ // If exact repay leaves a phantom FLOW debt type, this borrow would fail.
196+ borrowFromPosition (
197+ signer : user ,
198+ positionId : pid ,
199+ tokenTypeIdentifier : MOET_TOKEN_IDENTIFIER ,
200+ amount : 100.0 ,
201+ beFailed : false
202+ )
203+
204+ let details = getPositionDetails (pid : pid , beFailed : false )
205+ let flowDebt = getDebitBalanceForType (details : details , vaultType : CompositeType (FLOW_TOKEN_IDENTIFIER )! )
206+ let moetDebt = getDebitBalanceForType (details : details , vaultType : CompositeType (MOET_TOKEN_IDENTIFIER )! )
207+ Test .assert (flowDebt == 0.0 , message : " FLOW debt should be zero after exact repay" )
208+ Test .assert (moetDebt > = 100.0 - 0.01 , message : " MOET debt should be ~100 after new borrow" )
209+
210+ log (" \n === Test Complete: Exact Repay Clears Debt Type Constraint ===" )
211+ }
212+
213+ /// Regression: exact full collateral withdrawal should clear collateral-type constraints.
214+ /// After withdrawing FLOW collateral to exactly zero, depositing Dummy collateral should succeed.
215+ access (all )
216+ fun testExactFullWithdrawClearsCollateralTypeConstraint () {
217+ Test .reset (to : snapshot )
218+ log (" \n === Test: Exact Full Withdraw Clears Collateral Type Constraint ===\n " )
219+
220+ let user = Test .createAccount ()
221+ setupMoetVault (user , beFailed : false )
222+ setupDummyTokenVault (user )
223+ transferFlowTokens (to : user , amount : 2_000.0 )
224+ mintDummyToken (to : user , amount : 2_000.0 )
225+ grantBetaPoolParticipantAccess (PROTOCOL_ACCOUNT , user )
226+
227+ let createPosRes = executeTransaction (
228+ " ../transactions/flow-alp/position/create_position.cdc" ,
229+ [1_000.0 , FLOW_VAULT_STORAGE_PATH , false ],
230+ user
231+ )
232+ Test .expect (createPosRes , Test .beSucceeded ())
233+
234+ let pid : UInt64 = 0
235+
236+ // Withdraw collateral exactly to zero.
237+ withdrawFromPosition (
238+ signer : user ,
239+ positionId : pid ,
240+ tokenTypeIdentifier : FLOW_TOKEN_IDENTIFIER ,
241+ amount : 1_000.0 ,
242+ pullFromTopUpSource : false
243+ )
244+
245+ // If exact full withdraw leaves a phantom FLOW collateral type, this deposit would fail.
246+ depositToPosition (
247+ signer : user ,
248+ positionID : pid ,
249+ amount : 500.0 ,
250+ vaultStoragePath : DummyToken .VaultStoragePath ,
251+ pushToDrawDownSink : false
252+ )
253+
254+ let details = getPositionDetails (pid : pid , beFailed : false )
255+ let flowCredit = getCreditBalanceForType (details : details , vaultType : CompositeType (FLOW_TOKEN_IDENTIFIER )! )
256+ let dummyCredit = getCreditBalanceForType (details : details , vaultType : CompositeType (DUMMY_TOKEN_IDENTIFIER )! )
257+ Test .assert (flowCredit == 0.0 , message : " FLOW collateral should be zero after full withdrawal" )
258+ Test .assert (dummyCredit > = 500.0 - 0.01 , message : " Dummy collateral should be ~500 after deposit" )
259+
260+ log (" \n === Test Complete: Exact Full Withdraw Clears Collateral Type Constraint ===" )
261+ }
262+
144263// Helper functions
145264
146265access (all )
0 commit comments