Skip to content

fix: Reject stale AMM swaps in the mempool; one swap per pool per template - #55

Open
giaki3003 wants to merge 3 commits into
LayerTwo-Labs:masterfrom
giaki3003:fix/w3-20260702-2346-kimiclaw-confirm-glmclaw-p-plain-bitassets-ammswap-prevalidate-connect-gap-
Open

giaki3003 wants to merge 3 commits into
LayerTwo-Labs:masterfrom
giaki3003:fix/w3-20260702-2346-kimiclaw-confirm-glmclaw-p-plain-bitassets-ammswap-prevalidate-connect-gap-

Conversation

@giaki3003

Copy link
Copy Markdown
Contributor

What's wrong

An AmmSwap declares amount_receive, and that declaration is only checked against pool state in amm::apply_swap, at block connection. State::validate_transaction never checks it, so a swap that is stale with respect to the current pool state is accepted into the mempool and is not evicted by the checks in Node::get_transactions, which keeps selecting it into block templates that then fail to connect with Amm(InvalidSwap), stalling block production. The same happens with two swaps on one pool in a single template: both are validated against the pre-block state, but the second is applied after the first has moved the pool.

The fix

apply_swap's pool computation moves into a shared swap_pool_state, and a new amm::validate_swap is called from State::validate_transaction for swaps, so stale swaps are rejected on entry and dropped at template time. Block validation is unchanged — swaps in a block are still applied sequentially. Node::get_transactions also records the AmmPairs already swapped into the template and skips (leaving in the mempool) later swaps on the same pool; AmmPair gains PartialEq/Eq/Hash for that.

Tests

Adds validate_swap_rejects_stale_swap. It currently replaces apply_mint_burn_wrong_lp_baseline in that module, which wasn't intended scope — happy to restore that test alongside it.

Finding report (access-controlled): https://giaki3003.tech/#/findings/20260702-2346-kimiclaw-confirm-glmclaw-plain-bitassets-amm-swap-prevalidate-connect-gap


Part of a short series for this repo (fix 3 of 4); builds on #54, so it reads best merged after that one. Happy to rebase or split if you'd prefer them independent.

giaki3003 and others added 3 commits July 29, 2026 11:01
Bug: w3-20260630-1952-kimiclaw-confirm-openclaw- (primary)
Finding: findings/20260630-1952-kimiclaw-confirm-openclaw-plain-bitassets-dutch-auction-dust-bid-drain.md
Severity: R4-T1

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
(cherry picked from commit b3baea9)
…ty check on a mis-assigned n_unique_bitasset_outputs variable (filled from spent BitAsset INPUTS via unique_spent_bitassets() instead of the computed-but-unused bitasset_outputs() count), so a normal LP-redemption burn is deterministically rejected by block validation with Error::Amm(InvalidBurn)

Bug: w3-20260611-0220-bitassets-amm-burn-validat (primary)
Finding: findings/20260611-0220-bitassets-amm-burn-validator-counts-spent-bitassets-not-outputs-rejects-normal-burn.md
Severity: R4-T2

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
(cherry picked from commit caeb6d5)
… block

Bug: w3-20260702-2346-kimiclaw-confirm-glmclaw-p (primary)
Finding: findings/20260702-2346-kimiclaw-confirm-glmclaw-plain-bitassets-amm-swap-prevalidate-connect-gap.md
Severity: R4-T2

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
(cherry picked from commit 574f79d)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant