Fix MultiSwapper quote backcompat#161
Closed
liobrasil wants to merge 8 commits into
Closed
Conversation
…er-alex-backcompat
9237a3e to
9a266df
Compare
…er-alex-backcompat
618eefc to
f824ade
Compare
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 finishes the remaining
MultiSwapperfollow-up work after#158.It keeps the improved route-selection behavior from
#158, restores the outward quote semantics expected by existing callers, fixes the remaining partial-route tie case, and aligns the publicSwapperdocumentation with the actual quote model used by the implementations.Remaining Issues From
#158swap(nil, ...)andswapBack(nil, ...)could become inconsistent withquoteOut(...).In
#158,quoteOut(forProvided)could return an inner route's smaller executableinAmount, whileMultiSwapper._swap(...)still forwarded the full vault balance when it fell back toquoteOut(from.balance).That broke strict or capacity-limited inner swappers that enforce
input <= quote.inAmount.Example before this PR:
10 TokenA4 TokenBquoteOut(10)={ inAmount: 4, outAmount: 4 }_swap(...)still forwards the full10 TokenAvault10 > quote.inAmount (4)Example after this PR:
MultiSwapper.quoteOut(10)={ inAmount: 10, outAmount: 4 }swap(nil, ...)andswapBack(nil, ...)remain consistent with the full vault balance being swappedSwapSource.withdrawAvailable(maxAmount)could return more thanmaxAmount.quoteIn(forDesired)started exposing the chosen route's rawoutAmount, which can overshoot the requested amount due to rounding or quote refinement.SwapSourcethen forwarded that quote directly intoswap(...).Example before this PR:
withdrawAvailable(maxAmount: 10)quoteIn(10) = { inAmount: 10, outAmount: 11 }SwapSourceforwards that quote directly intoswap(...)11, even thoughmaxAmountwas10Example after this PR:
MultiSwapper.quoteIn(10)is clamped to{ inAmount: 10, outAmount: 10 }SwapSource.withdrawAvailable(maxAmount: 10)cannot return more than10quoteIn(...)still had a partial-route tie regression.When no route could fully satisfy
forDesired,#158preferred the partial route with the highestoutAmount, but if two partial routes had the sameoutAmountit kept the first one seen even if another route required less input.Example before this PR:
{ inAmount: 10, outAmount: 5 }{ inAmount: 5, outAmount: 5 }quoteIn(forDesired: 10)outAmount = 5#158keeps Route A if it appears first, even though Route B is strictly betterExample after this PR:
quoteIn(forDesired: 10)still falls back to the best partial routeoutAmountis broken by lowerinAmountThe public
Swapperinterface comments were still not aligned with implementation behavior.The
reverseflag flips the quoted token types, but the quote amounts still describequote.inType -> quote.outTypein the chosen direction.Example before this PR:
reverse=trueshould be interpreted as “provideforDesiredoutput tokens and receivequote.inAmountinput tokens”quote.inAmountandquote.outAmountstill describe the swap in the quoted direction, with only the token types flippedExample after this PR:
quote.inAmountalways refers toquote.inTypequote.outAmountalways refers toquote.outTypereverseis documented as changing the quoted token direction, not redefining what the quote fields meanFix
MultiSwapper._estimate(...)helper that selects the winning route while preserving the improved#158route-selection rules.quoteIn(...), keep the selected route'sinAmount, but clamp the outwardoutAmounttoforDesired.quoteOut(...), keep the selected route'soutAmount, but preserveinAmount = forProvidedin the outward quote.quoteOut(...)preferring the highestoutAmount, with lowerinAmountas a tiebreak when routes tie on output.quoteIn(...)preferring full coverage over partial coverage, and prefer lowerinAmountwhen partial routes tie onoutAmount.Swapperinterface documentation so the quote semantics andreversebehavior match the current implementations.Tests
flow test ./cadence/tests/SwapConnectorsMultiSwapper_test.cdcAdded or expanded regression coverage for:
quoteIn(...)andquoteOut(...)quoteIn(...)partial-route tie breaking on lowerinAmountquoteOut(...)preserving the caller-provided input amount on capped routesswap(nil, ...)succeeding against a strict capped inner swapperSwapSource.withdrawAvailable(maxAmount)never returning more thanmaxAmountquoteOut(...)route-selection behavior, including capped and partial-consumption routes