Add flash CCR rebalancer#8915
Draft
Mo-Hussain wants to merge 2 commits into
Draft
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #8915 +/- ##
==========================================
- Coverage 79.33% 79.32% -0.02%
==========================================
Files 143 144 +1
Lines 4278 4473 +195
Branches 436 479 +43
==========================================
+ Hits 3394 3548 +154
- Misses 855 895 +40
- Partials 29 30 +1
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
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
Adds
FlashCcrRebalancer, a helper contract for atomically rebalancing same-chain CrossCollateralRouter collateral pools with a flashloan and caller-supplied swap calldata.The intended use case is CROSS/moonpay-style inventory balancing where one asset, e.g. USDC, is deficient on a chain and the paired same-chain asset, e.g. USDT, is surplus. The helper borrows the deficient token, sends it through same-chain CCR
transferRemoteTo, receives the surplus token, swaps back into the borrowed token, tops up bounded shortfalls if needed, and repays the flashloan in the same transaction.Design Diagram
flowchart LR Operator[Allowlisted rebalancer] Helper[FlashCcrRebalancer] Flash{Flashloan provider} Aave[Aave V3 flashLoanSimple] Uni[Uniswap V3 pool flash] Deficit[Deficit CCR router] Surplus[Surplus CCR router] Swap[Allowlisted swap target] Spender[Allowlisted allowance target] TopUp[Top-up payer] Refund[Refund recipient] Operator -->|rebalance params| Helper Helper -->|borrow deficit token| Flash Flash --> Aave Flash --> Uni Aave -->|callback + borrowed token| Helper Uni -->|callback + borrowed token| Helper Helper -->|approve exact CCR debit| Deficit Deficit -->|transferRemoteTo localDomain, recipient=helper, target=surplus router| Surplus Surplus -->|surplus token| Helper TopUp -.->|optional surplus top-up before swap| Helper Helper -->|bounded approval amountInMax| Spender Helper -->|call supplied calldata/value| Swap Spender -->|pull surplus token if route requires| Helper Swap -->|deficit token output| Helper TopUp -.->|optional deficit top-up for CCR fee or repayment shortfall| Helper Helper -->|repay amount + fee/premium| Flash Helper -->|unused top-up / route residue| RefundMotivation
The design reduces the amount of route inventory that needs to be held by, approved to, or moved out of adapter contracts during a rebalance. Instead of staging assets in an executor or adapter and relying on a multi-step operational flow, the whole rebalance is one atomic transaction:
This gives us the useful flashloan property discussed in the design thread: the repayment requirement narrows the asset-loss surface because the borrowed asset, CCR transfer, swap, top-up, and repayment must all succeed together.
High-Level Flow
rebalancewith flashloan, CCR, swap, top-up, refund, and deadline params.flashLoanSimple, orflash.msg.senderis the allowlisted active providertransferRemoteToand sums only deficit-token quote amounts.transferRemoteTo(localDomain, helper, amount, surplusRouter).minSurplusReceived.swap.amountInMax, the helper pulls bounded surplus-token top-up from the configured payer.allowanceTargetfor at mostamountInMax, calls the configured swaptargetwith calldata/value, then clears the approval.minAmountOut.amount + premium, letting Aave pull repaymentamount + feeback to the pool during callbacktopUp.payerrefundToProvider Configuration
The contract is intentionally configurable but bounded by owner-managed allowlists:
allowedRebalancers[caller]allowedFlashLoanProviders[provider][pool]allowedSwapTargets[target]allowedAllowanceTargets[spender]Supported flashloan providers in this PR:
flashLoanSimpleflashThe provider enum keeps callback semantics explicit because Aave and Uniswap repay differently.
swaps.xyz / Swap Calldata Design
The helper does not integrate directly with swaps.xyz onchain. Instead, swaps.xyz remains an offchain quote/calldata provider.
The expected integration shape is:
SwapCall:target: returnedtx.toallowanceTarget: returned approval/spender address, which may differ fromtx.totokenIn: surplus token received from CCRtokenOut: borrowed/deficit tokenamountInMax: maximum surplus token the helper may approve/spendminAmountOut: minimum deficit-token balance increase requiredvalue: returned native value, if anydata: returned calldataThe contract does not decode or trust the route internals. It enforces the local invariants around that calldata:
amountInMaxminAmountOutThis supports both simple Uniswap-style call targets and aggregator-style flows where
tx.toand ERC20 spender are separate addresses.Top-Up Model
The helper supports both top-up directions discussed in the design thread:
maxSurplusTokenTopUpfromtopUp.payer.maxDeficitTokenTopUp.Unused surplus-token top-up is refunded to
topUp.payerbefore any generic residue sweep. Residue that came from the route itself is swept torefundTo.Safety Properties
Important invariants enforced by the implementation:
maxDeficitTokenDebitTests
Adds focused Solidity coverage for:
refundToVerification
forge test --match-path test/rebalancing/FlashCcrRebalancer.t.solforge build --skip test --contracts contracts/rebalancing/FlashCcrRebalancer.solFollow-Up / Rollout Notes
This PR adds the contract and focused unit coverage. Before production use, the next steps should be:
RebalanceParamsfrom route imbalance analysis