fix: prevent closePosition panic when withdrawals map is empty#195
Open
fix: prevent closePosition panic when withdrawals map is empty#195
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes an edge-case panic in
closePositionwhen the position has no debt and no remaining collateral at close time.Real panic scenario (before this fix)
100.0 FLOW.100.0 FLOW.repay_and_close_position.cdcto close.At this point in
closePosition:debtsByType = {}(no debt to repay),collateralTypes = [],_withdrawAllCollateral(...)returnsvaults = [].The old code then built
withdrawalsByTypewith:for i in InclusiveRange(0, vaults.length - 1)With
vaults.length == 0, this range evaluates toInclusiveRange(0, -1)(which iterates0, -1).The first iteration tries
vaults[0]on an empty array, causing an out-of-bounds runtime panic and reverting close.Root cause
Using an index-based loop that assumes a non-empty array when building
withdrawalsByType.Fix
In
FlowALPv0.cdcclose flow, replaced the inclusive-range index loop with a bounds-safe loop:var i = 0while i < vaults.length { ...; i = i + 1 }This preserves behavior for non-empty arrays and safely no-ops for empty arrays.
Why this is safe
withdrawalsByType) and only affects iteration safety.Tests
Added regression test:
cadence/tests/close_position_empty_position_test.cdcThe test executes the real scenario above and asserts close succeeds without panic and funds are returned as expected.
Also re-ran existing close-related tests to ensure no regressions:
close_position_dust_return_test.cdcclose_position_precision_test.cdcclose_position_queued_overpayment_test.cdcclose_position_rounding_overpayment_test.cdcRisk / Compatibility