feat(provider): assert expectedCenterRate on rebalance - #227
Merged
Conversation
rebalance takes an expectedCenterRate the BOT reads via the new adapter centerRate() view and passes back; if the live LST↔native rate deviates from it by more than maxCenterRateDeviationBps the call reverts. This bounds the range anchor against a rate anomaly between build and execution — invisible to the fair-NAV loss caps, which measure in the same rate frame. Both sides opt in (expectedCenterRate != 0 per-call, maxCenterRateDeviationBps != 0 globally); 0 preserves prior behavior. Adds the MANAGER setter, the centerRate() getter, and doc-faithful counter-tests (real slippage/target floors, not zeros). Storage is append-only (upgrade-safe). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
v0.1.1 false-positived V3DexAdapter's __gap consumption (it read the __gap array shrink 45->44 as a type change at the gap slot). v0.1.2 is __gap-aware: the standard pattern — shrink __gap and place the new variable in the freed slot — validates as UPGRADE SAFE, so the committed maxCenterRateDeviationBps layout passes without contorting the storage. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
📄 Description
Adds a BOT-asserted center-rate guard to
rebalance. The BOT reads the live LST↔native rate via the newadapter.centerRate()view and passes it back asexpectedCenterRate; if the on-chain rate deviates fromit by more than
maxCenterRateDeviationBps, the call reverts (CenterRateDeviationTooHigh).🧠 Rationale
The range center comes from the on-chain LST↔native rate, but the fair-NAV loss caps measure the rebalance
before/after in that same rate frame — so a rate anomaly between the BOT's build and on-chain execution
is invisible to them, and the position could be recentered (and inventory converted) around a bad anchor.
This guard bounds the anchor independently, symmetric with the existing
targetSqrtPriceX96spot-deviationgate. Both sides opt in (
expectedCenterRate != 0per-call,maxCenterRateDeviationBps != 0globally);0preserves prior behavior, so it's backward-compatible and storage is append-only (upgrade-safe).
🧪 Example / Testing
Doc-faithful counter-tests in
SlisBNBV3Provider.t.sol(real slippage/target floors, not zeros):test_rebalance_revertsOnCenterRateMismatch— otherwise-valid params + a 2%-offexpectedCenterRatestill reverts (guard fires before any burn/mint).test_rebalance_passesWithinCenterRateBand—expectedCenterRate == centerRate()clears the guard; the full recenter completes and stays value-neutral.test_rebalance_centerRateGuardOffByDefault— default band0ignores a wrong rate while the real slippage/target guards still apply.Full provider suite green (
forge test --match-path "test/provider/*"→ 376 passed; needsBSC_RPC/ETH_RPC).🧬 Changes Summary
rebalancegains anexpectedCenterRateparam (adapter,IV3DexAdapter,V3Provider._guardedRebalance, and the slisBNB/wstETH/wbETH wrappers); the assertion fires before any mint.maxCenterRateDeviationBpsstorage (append-only) + MANAGER setter + event; newCenterRateDeviationTooHigherror.centerRate()view (adapter + interface) so the BOT can read the live rate to pass back.0(unchanged behavior).🤖 Generated with Claude Code