Event-source Balancer V2 swaps - #33
Merged
Merged
Conversation
Extend the exact-write posture (V2/Solidly `Sync`, V3 `Mint`/`Burn`) to Balancer V2 `Swap`s: apply each swapped token's exact vault `cash` delta directly from the event's `amountIn`/`amountOut` with no RPC, falling back to a balance-slots resync only where a token's cash location is unknown. Mechanism - Vault balances pack as [lastChangeBlock:32][managed:112][cash:112]; a swap changes only the 112-bit `cash` field, by exactly +/-amount (protocol fees settle lazily on join/exit, so there is no per-swap skim -- verified live). - `BalancerTokenBalance` records each token's (slot, high_field). The discover cold-start probes it by matching getPoolTokens balances to warmed slot cash fields -- specialization-agnostic (TWO_TOKEN shared slot + GENERAL/MINIMAL per-token slots); ambiguous/zero/managed matches are skipped -> resync. - TWO_TOKEN's two fields share one word, so both deltas accumulate into a single write (two writes from one pre-image would clobber). - `PoolBalanceChanged` (join/exit) is now subscribed: it routes + resyncs the balances (event-sourcing its deltas is a follow-up). `token_cash` is built in discover mode and carried through verify-only cold starts, so event-sourcing works after either path; a slots-only pre-population safely falls back to resync. Tests - 7 inline unit tests: cash-field round-trips, RMW add/sub/overflow/underflow, probe (TWO_TOKEN + GENERAL + ambiguous-skip), event_source_swap (shared-slot accumulation, separate slots, unknown/cold -> None). - 4 reactive integration tests: warm TWO_TOKEN + GENERAL event-sourcing (Exact, no resync), unmapped-swap resync fallback, PoolBalanceChanged route+resync. - Live RPC parity (env-gated, #[ignore]): for a real TWO_TOKEN and GENERAL swap, trace_replayTransaction(stateDiff) confirms the event-sourced cash fields reproduce the on-chain per-tx values exactly. Offline gate green: tests (all-features/default/no-default), clippy -D warnings (all-features + no-default), doc -D warnings (missing_docs), fmt. Also fmt-normalizes 2 pre-existing nits in the Curve files inherited from the base commit (same rustfmt the repo uses). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
KaiCode2
force-pushed
the
feat/balancer-event-sourcing
branch
from
July 7, 2026 16:53
ad6889c to
50cb65b
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
Swaplogs into warmed vault cash slots when cold-start has probed token cash locationsFinal review changes
TWO_TOKENpools never treat the high managed-balance field as cashValidation
git diff --checkcargo fmt --all --checkcargo clippy --all-targets --all-features --no-deps -- -D warningscargo test --all-featurescargo test --no-default-featurescargo package --locked --allow-dirtyLive RPC parity tests remain
#[ignore]/ env-gated and were not run withoutE2E_RPC_URL.