docs: record the one-sided target pair check for the Celo LP swap - #349
Merged
Conversation
LPSwapCelo guards a pre-existing target pair whose reserves are skewed, by deriving minimum amounts from the TWAP-protected removal. It does not cover a pair seeded on one side only: the router branches on reserves, and a (X, 0) pair is neither the both-zero case nor quotable, so UniswapV2Library.quote reverts INSUFFICIENT_LIQUIDITY before the minimums are consulted. The guard is bypassed rather than triggered, which is why the revert reads as unrelated to slippage - and creating and seeding the pair is permissionless. Nothing is lost when it happens: the transaction is atomic so the source LP removal rolls back. But the pair keeps its state, so retries fail identically until it is repaired - and the repair is permissionless too, needing no privileged key. Recorded in the two places an operator would look: a pre-flight block on proposal_23, which is the script actually run, with the cast call to read the reserves and the dust-plus-sync repair; and as runbook section 3.4, alongside the V3 initialize() front-run it mirrors.
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.
Operational follow-up to vulnerabilities list entry 37.
LPSwapCeloalready guards a pre-existing target pair whose reserves are skewed, by deriving minimum amounts from the TWAP-protected removal. It does not cover a pair seeded on one side only: the router branches on reserves, and a(X, 0)pair is neither the both-zero case nor quotable, soUniswapV2Library.quoterevertsINSUFFICIENT_LIQUIDITYbefore the minimums are consulted.The guard is bypassed rather than triggered — which is why the revert reads as unrelated to slippage, and why this is worth writing down rather than leaving to be diagnosed live. Creating and seeding the pair is permissionless.
Nothing is at risk when it happens. The transaction is atomic, so the source LP removal rolls back. But the pair keeps its state, so retries fail identically until it is repaired — and the repair is permissionless too, so it needs no privileged key or governance action.
Recorded in the two places an operator would look
proposal_23_transfer_lp_token_celo.sh, which is the script actually run — with thecast callto read the reserves and the dust-plus-sync()repair.initialize()front-run, which is the same family of problem on the V3 side.No code change.